简体   繁体   中英

Using fread and fwrite .. data loss

Hi I am trying to read a binary file and process it but I think I am using fread wrong way, when I try to use fread the no. of bytes read are less then the size of file. can anyone help me, white I am doing wrong

    #include <stdio.h>
    #include <limits.h>

    int main()
    {

    FILE *fin=fopen("./file.pcap","rb");

    char line[LINE_MAX];

    FILE *fout=fopen("out.txt","w");

    while(fread(line,sizeof(line),1,fin)){
        fwrite(&line,sizeof(line),1,fout);
    }

    fclose(fin);
    fclose(fout);

    }

The first file is around 51236 and out.txt is 51200

Fread returns the number of "elements" read. You have said an element is LINE_MAX bytes long, so when you get to the end of the file, there is not a full element for you, so fread() returns 0 and your output ends up truncated.

try flipping to read "a number of bytes" rather than "1 block of LINE_MAX bytes":

size_t numBlocks;
while((numBlocks = fread(line, 1, sizeof(line), fin)) > 0) {
    fwrite(line, 1, numBlocks, fout);
}

Because you're asking for LINE-MAX -sized blocks, you won't get the final one if the file size isn't an exact multiple of that value. fread returns the number of complete blocks that it read. You would be better off using something like:

size_t sz;
while ((sz = fread (line, 1, sizeof (line), fin)) > 0) {
    fwrite (line, sz, 1, fout);
}

This will read any amount of data (up to LINE_MAX ) from the input file and then write a block of that size out to the output file. It does so because, instead of saying one block of size LINE_MAX , you specify LINE_MAX blocks each of one byte. That way, if there aren't LINE_MAX characters left in the file, fread will just give you as many as it can.

The end of file will result in fread returning zero, any other value means data was read successfully.

As an aside, you should also check the return value from fwrite . You don't have to swap the arguments for that one but you should ensure that the return value is 1 (or sz if you do swap the arguments). Otherwise, the data wasn't necessarily all written.

In other words:

size_t sz;
while ((sz = fread (line, 1, sizeof (line), fin)) > 0) {
    if (fwrite (line, sz, 1, fout) != 1) {
        // Handle error.
    }
}

You're close, but fread() is going to return 0 when it gets the partial buffer at the end of your input file. You need to add some code to handle that case, or else you'll skip writing those bytes out.

The & in your fwrite() call is also unnecessary, but that's not related to your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM