简体   繁体   中英

Can't correctly copy data from one file to another with fwrite()

"image" is a pointer to a file from which I want to copy data, and "new_image" is pointer to the directory where to I want to copy data. I do it in a loop, so after each time data is copied from image to new_image both pointers need to update. For some reasons, combination below gives incorrect result.

fwrite(image, sizeof(BYTE), 512, new_image);
fseek(image, 512, SEEK_CUR);

The entire code:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint8_t BYTE;

BYTE check(FILE *image, BYTE array[])
{
    BYTE holder;
    for (int i = 0; i < 3; i++)
    {
        //printf("%li and %i ", ftell(image), i);
        if (fread(&holder, 1, 1, image) == 0)
        {
            return 0;
        }
        if (holder != array[i])
        {
            return i + 1;
        }
    }

    fread(&holder, 1, 1, image);
    if (!(holder >= 0xe0 && holder <= 0xef))
    {
        return 4;
    }

    return holder;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./recover file_name.raw\n");
        return 1;
    }

    FILE *image = fopen(argv[1], "r");
    if (image == NULL)
    {
        printf("No such file\n");
        return 2;
    }

    BYTE array[] = {0xff, 0xd8, 0xff};

    int i = 0;
    int number = 0;
    BYTE m;
    char name[8];
    long images[51];

    while (1)
    {
        m = check(image, array);
        if (m == 0)
        {
            images[i] = ftell(image);
            break;
        }
        number++;
        if (m > 4)
        {
            fseek(image, -4, SEEK_CUR);
            images[i] = ftell(image);
            i++;
            fseek(image, 512, SEEK_CUR);
        }
        else
        {
            fseek(image, 512 - m, SEEK_CUR);
        }
    }

    fseek(image, images[0], SEEK_SET);
    //printf("%li\n", ftell(image));

    for (int j = 0; j < 50; j++)
    {
        if (j > 9)
        {
            sprintf(name, "0%i.jpg", j);
        }
        else
        {
            sprintf(name, "00%i.jpg", j);
        }

        FILE *new_image = fopen(name, "w");
        BYTE example[512];

        while (ftell(image) != images[j + 1])
        {
            fread(example, sizeof(BYTE), 512, image);
            fwrite(example, sizeof(BYTE), 512, new_image);
            //fseek(image, 512, SEEK_CUR);
        }

        FILE *new_read = fopen(name, "r");

            fseek(new_read, 0, SEEK_SET);
            BYTE variable;
            if (check(new_read, array) > 4)
            {
                printf("GOOd\n");
            }
            else
            {
                fseek(new_read, 0, SEEK_SET);
                fread(&variable, sizeof(BYTE), 1, new_read);
                printf("%i\n", variable);
            }

        fclose(new_read);
        fclose(new_image);
    }

    fclose(image);
}

However, if I change the code to this:

fread(example, sizeof(BYTE), 512, image);
fwrite(example, sizeof(BYTE), 512, new_image);

where "example" is an (uint8_t) array of length 512, the code works properly. Could someone explain why is that?

fwrite(image, sizeof(BYTE), 512, new_image);

This line is faulty. The first parameter to fwrite needs to be a pointer to a buffer like example (which is then written to the file identified by the handle provided as a fourth parameter, new_image in this case). What you are trying to do here instead is writing from image (which is another file handle , not a data buffer) into new_image .

image does not point to the file data. It is a pointer to a FILE struct, which you should never read from or write to directly.

( FILE is implementation-specific, but usually consists of some kind of OS-specific identifier -- like the file ID returned by open() on POSIX -- a pointer to an optional file buffer that might or might not be filled at any given time, and a couple of data bits for the standard library to determine file position, buffer status, error flags etc.; it is not identical to a file's contents.)

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