Thread: binary files: copying jpeg or video files

  1. #1
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242

    binary files: copying jpeg or video files

    Hi all.

    I have created the below code to copy text files, and would now like to write code to copy non-text files(pics, music, video).

    I think that I need to use fread() and fwrite() for binary files. Something like:

    Code:
    while((fread(...)) != NULL)
        fwrite(...)
    But I don't know how to determine the size and n x size arguments for fread() and fwrite().

    So I have some questions:

    1. How do I know if a jpg or video file is made up of int or float etc?
    2. Do I need code to detect the size of a file?
    3. Can I use fseek() or feof() to detect the size of a file?
    4. Do I actually need to use fread() & fwrite() or are there better functions for the job?

    Thanks in advanced.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAXLINELENGTH 100
    #define FILENAMELENGTH 30
    
    int main(void)
    {
        char file1[FILENAMELENGTH], file2[FILENAMELENGTH], line[MAXLINELENGTH];
        FILE *openfile1, *openfile2;
        printf("Enter file to copy: ");
        fgets(file1, FILENAMELENGTH, stdin);
        file1[strlen(file1) - 1] = '\0';
    
        if((openfile1 = fopen(file1, "r")) != NULL)
            printf("%s opened successfully\n", file1);
        else
        {
            perror("error");
            exit(1);
        }
    
        printf("Enter file to copy to: ");
        fgets(file2, MAXLINELENGTH, stdin);
        file2[strlen(file2) - 1] = '\0';
    
        if((openfile2 = fopen(file2, "w")) != NULL)
            printf("%s was copied successfully to %s\n", file1, file2);
        else
        {
            perror("error");
            exit(1);
        }
    
        while((fgets(line, MAXLINELENGTH, openfile1)) != NULL)
            fputs(line, openfile2);
    
        fclose(openfile1);
        fclose(openfile2);
    
        return 0;
    }
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    The data is all binary whether it represents text or floats or ints or whatever. You don't have to assume it is ints or floats just take it as bytes of data and read in chunks of whatever size bytes you want to deal with. Read in a chunk of size X bytes from the source file and then write out size X bytes to the destination file.

    You don't really need to detect the size of the file. You just have your loop that continuously reads/writes data until there is no more data in the source file to read. At that point you can exit the loop. If you code the exit condition for this loop the wrong way, then you may need to do one more write after the loop. If you do it correctly, then you won't.

    Use fread and fwrite and not the other functions that are geared towards text. These other functions would have issues dealing with embedded nulls (zeroes) in the source file and would cause trouble.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    Thanks hk_mp5kpdw!
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  4. #4
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    Works now!

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define FILENAMELENGTH 30
    #define LINELENGTH 100
    
    int main()
    {
        FILE *openfile, *openfile2;
        char file1[FILENAMELENGTH], file2[FILENAMELENGTH], line[LINELENGTH];
    
        printf("Enter file to copy: ");
        fgets(file1, FILENAMELENGTH, stdin);
        file1[strlen(file1) - 1] = '\0';
        printf("Enter file to copy to: ");
        fgets(file2, FILENAMELENGTH, stdin);
        file2[strlen(file2) - 1] = '\0';
    
        if((openfile = fopen(file1, "rb")) != NULL)
           printf("%s opened successfully\n", file1);
        else
        {
            perror("Error");
            exit(1);
        }
    
        if((openfile2 = fopen(file2, "wr")) != NULL)
            printf("%s opened successfully\n", file2);
        else
        {
            perror("Error");
            exit(1);
        }
    
        while(fread(line, 1, LINELENGTH, openfile) == LINELENGTH)
            if((fwrite(line, 1, LINELENGTH, openfile2)) != LINELENGTH)
            {
                puts("Error writing to file");
                exit(1);
            }
    
        fclose(openfile);
        fclose(openfile2);
    
        return 0;
    }
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Your code will only copy a multiple of LINELENGTH bytes. You want something like this:
    Code:
    size_t n;
    while ((n = fread(line, 1, LINELENGTH, openfile)) > 0)
        if (fwrite(line, 1, n, openfile2) != n)
    Also, your value for LINELENGTH is a little small. Something like 1024 (1K) or 4096 (4K) is more sensible.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    945
    Quote Originally Posted by cfanatic View Post
    Works now!

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define FILENAMELENGTH 30
    #define LINELENGTH 100
    
    int main()
    {
        FILE *openfile, *openfile2;
        char file1[FILENAMELENGTH], file2[FILENAMELENGTH], line[LINELENGTH];
    
        printf("Enter file to copy: ");
        fgets(file1, FILENAMELENGTH, stdin);
        file1[strlen(file1) - 1] = '\0';
        printf("Enter file to copy to: ");
        fgets(file2, FILENAMELENGTH, stdin);
        file2[strlen(file2) - 1] = '\0';
    
        if((openfile = fopen(file1, "rb")) != NULL)
           printf("%s opened successfully\n", file1);
        else
        {
            perror("Error");
            exit(1);
        }
    
        if((openfile2 = fopen(file2, "wr")) != NULL)
            printf("%s opened successfully\n", file2);
        else
        {
            perror("Error");
            exit(1);
        }
    
        while(fread(line, 1, LINELENGTH, openfile) == LINELENGTH)
            if((fwrite(line, 1, LINELENGTH, openfile2)) != LINELENGTH)
            {
                puts("Error writing to file");
                exit(1);
            }
    
        fclose(openfile);
        fclose(openfile2);
    
        return 0;
    }
    Did you test it on a file that has a size that is not a multiple of 100? This program will truncate the destination to a multiple of 100 because you write to the destination only when you successfully read all 100 characters from the source. fread might return a short value (between 0 and 99, inclusive) if it reaches the end of file, but your code doesn't handle that case. You need to save the number of characters read by fread so you can write the same number of characters with fwrite.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Copying Binary Files
    By mikeman118 in forum C++ Programming
    Replies: 9
    Last Post: 08-11-2007, 10:55 PM
  2. copying jpeg files
    By adk1283 in forum C++ Programming
    Replies: 9
    Last Post: 08-11-2005, 04:44 PM
  3. Moving files/deleting files/ copying, etc
    By Nakeerb in forum C++ Programming
    Replies: 1
    Last Post: 10-11-2002, 05:45 PM
  4. Copying binary files, like ZIPs
    By frenchfry164 in forum C++ Programming
    Replies: 4
    Last Post: 03-16-2002, 03:54 PM
  5. using jpeg files
    By phantom in forum C++ Programming
    Replies: 3
    Last Post: 02-19-2002, 01:33 AM