Thread: Reading data from volumes

  1. #16
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Don't be discouraged. Salem's just pulling your leg.

    Here's a bit of a rewrite for you. I tried to make the "CreateArchive" function able to create either an archive with volumes or without, depending on whether volSize is 0 or not. I haven't tested it, though, so you may have to fix a few things.

    Code:
    #define MIN_ARGS 4
    #define BUFFER_SIZE 4096
    
    FILE *OpenVolumeFile(char *volumeName, int volume) {
        char volumeName[256];
        FILE *fArchive;
        if (volume > 0)
            sprintf(volumeName, "%s-%d", archiveName, volume);
        else
            sprintf(volumeName, "%s", archiveName);
        if (!(fArchive = fopen(volumeName, "wb", fArchive))
            Error("No file handle\n");
        return fArchive;
    }
    
    size_t ReadBuffer(FILE *fin, char *buffer, size_t bytesToRead) {
        size_t bytesRead;
        bytesRead = fread(buffer, 1, bytesToRead, fData);
        if(bytesRead < bytesToRead) Error("fread failure");
        return bytesRead;
    }
    
    size_t WriteArchiveHeader(FILE *fArchive, size_t volSize, int numFiles,
                              char *fileNames, size_t *fileSizes);
    {
        size_t headerSize = sizeof numFiles + sizeof volSize +
                     numFiles * (sizeof *fileSizes + sizeof (size_t));
        if( fwrite(&numFiles, sizeof(numFiles), 1, fArchive) != 1)
            Error("Error writing number of files to bin\n");
        if( fwrite(&volSize, sizeof(volSize), 1, fArchive) != 1)
            Error("Error writing volume size to bin\n");
        for(i = 0; i < numFiles; i++)
        {
            size_t fileNameLen = strlen(fileNames[i]);
            WriteArchiveHeaderRecord(fArchive, fileNames[i], fileNameLen, fileSizes[i]);
            headerSize += fileNameLen;
        }
        printf("Wrote file header -> Size: %d\n\n", headerSize);
        return headerSize;
    }
    
    void CreateArchive(
        char   *archiveName,
        size_t  volSize,
        int     numFiles,
        char   *fileNames)
    {
        FILE   *fArchive;
        size_t  volBytesLeft;
        size_t  headerSize;
        size_t  fileSizes[numFiles]; // I got rid of the "file" struct
        int     i;
        int     volume = 0;
    
        for(i = 0; i < numFiles; i++)
            fileSizes[i] = GetFileSize(fileNames[i]);
    
        fArchive = OpenVolumeFile(archiveName, volSize>0 ? ++volume : 0);
        headerSize = WriteArchiveHeader(fArchive, volSize, numFiles, fileNames, fileSizes);
        if (volSize > 0)
            volBytesLeft = volSize - headerSize;
        else
            volBytesLeft = BUFFER_SIZE + 1; // ensure that it's greater than buffer size
    
        for(i = 0; i < numFiles; i++)
        {
            size_t fileBytesLeft = fileSizes[i];
    
            FILE *fData = fopen(fileNames[i], "rb");
            if(fData == NULL)  Error("Error opening file\n");
    
            printf("File %i: %.2f MB\n", i + 1, (double)fileSizes[i] / 1024 / 1024);
    
            do
            {
                char buffer[BUFFER_SIZE];
                size_t bytesToRead, bytesRead;
    
                if(volBytesLeft == 0)
                {
                    fclose(fArchive);
                    fArchive = OpenVolumeFile(archiveName, ++volume);
                    volBytesLeft = volSize;
                }
    
                bytesRead = ReadBuffer(fData, buffer,
                                min3(sizeof buffer, fileBytesLeft, volBytesLeft));
                WriteBuffer(fArchive, buffer, bytesRead);
    
                fileBytesLeft -= bytesRead;
                if (volSize > 0)
                    volBytesLeft -= bytesRead;
            }
            while(fileBytesLeft > 0);
    
            fclose(fData);
            printf("Wrote file %i: %s\n\n", i + 1, argv[i + MIN_ARGS - 1]);
        }
    
        fclose(fArchive);
        printf("Success!");
    }
    
    // Call from main:
       CreateArchive(
           &argv[2],
           (size_t)atoi(argv[1])*1024*1024,
           argc - MIN_ARGS + 1,
           &argv[3]);
    Last edited by oogabooga; 05-08-2012 at 04:52 PM.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  2. #17
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    I've been able to fix most of the errors (25 or so), but I'm getting linker errors saying undefined reference to WriteArchiveHeaderRecord and WriteBuffer. Are those names for functions I have already written?

  3. #18
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Yes. I remember one of them was called WriteChunkBin (I think that's what I called WriteBuffer). I can't remember what the other was called, but it writes the file size, name length, and name to the header.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Read size of data array when reading .txt data
    By Taquito in forum C Programming
    Replies: 13
    Last Post: 04-29-2007, 01:52 AM
  2. Replies: 1
    Last Post: 10-22-2005, 05:28 AM
  3. windows volumes
    By valis in forum Windows Programming
    Replies: 0
    Last Post: 08-18-2005, 11:23 AM
  4. Replies: 2
    Last Post: 06-16-2005, 10:03 AM
  5. volumes and areas
    By oscuro in forum C++ Programming
    Replies: 1
    Last Post: 04-02-2002, 10:27 PM