Software & Finance





C++ - Copying Binary Files using STL and FILE * stream





Both CopyFile1 and CopyFile2 functions does exactly the same work except the former uses the STL fstream and the later uses the FILE * stream. 

Note that both input and output files are opened in binary mode. If you mix the mode, then you will get into problem. For example, if you open the file in binary mode for reading and uses text mode for writing, then you might see the increasd destination file size. This is because binary mode file operation treats new line characters \r and \n as two different character whereas text mode file operation treats both \r\n as one character.

 

In Text Mode, When you write "\n", "\r\n" are written into the file and in the same way when it is reading "\r\n", it will be read as "\n" only.

 

This program uses the command line arguments as input. Note that I have used USES_CONVERSION macro to convert TCHAR to const char *. The complete program and test run output are given below:



Source Code


#include <tchar.h>

#include <iostream>

#include <fstream>

#include <atlbase.h>

#include <atlconv.h>

 

bool CopyFile2(const char *srcFileName, const char *destFileName)

{

    FILE *istream = fopen(srcFileName, "rb");

    FILE *ostream = fopen(destFileName, "wb");

 

    // Opening istream in binary mode and writing in text mode will

    // increase the file size as \r\n are treated two characters in

    // binary mode where as one character in text mode

 

    if (istream == 0 || ostream == 0)

        return false;

 

    const int len = 4096;

    char buf[4096];

 

    while(1)

    {

        if( feof(istream))

            break;

        int nBytesRead = fread(buf, 1, len, istream);

        if(nBytesRead <= 0)

            break;

        fwrite(buf, 1, nBytesRead, ostream);

    }

 

    fclose(istream);

    fclose(ostream);

    return true;

}

 

bool CopyFile1(const char *srcFileName, const char *destFileName)

{

    std::ifstream ifs(srcFileName, std::ios::binary | std::ios::in);

    std::ofstream ofs(destFileName, std::ios::binary | std::ios::out);

 

    if(ifs.is_open() == false || ofs.is_open() == false)

        return false;

 

    // Opening istream in binary mode and writing in text mode will

    // increase the file size as \r\n are treated two characters in

    // binary mode where as one character in text mode

 

    const int len = 4096;

    char buf[4096];

    while(1)

    {

        if(ifs.eof())

            break;

        ifs.read(buf, len);

        int nBytesRead = ifs.gcount();

        if(nBytesRead <= 0)

            break;

        ofs.write(buf, nBytesRead);

    }

    ifs.close();

    ofs.close();

 

    return true;

}

 

int _tmain(int argc, TCHAR* argv[])

{

    if( argc != 4)

    {

        std::cout << "FILECOPY.EXE <source filename> <dest1 filename> <dest2 filename>]";

        return 0;

    }

 

    USES_CONVERSION;

 

    const char *p1 = T2A (argv[1]);

    const char *p2 = T2A (argv[2]);

    const char *p3 = T2A (argv[3]);

 

 

    if(CopyFile1(p1, p2) == true)

        std::cout << p1 << " is copied to " << p2 << "\n";

    else

        std::cout << "Error in copying " << p1 << " to " << p2 << "\n";

 

    if(CopyFile2(p2, p3) == true)

        std::cout << p2 << " is copied to " << p3 << "\n";

    else

        std::cout << "Error in copying " << p2 << " to " << p3 << "\n";

       

      return 0;

} 

Output


c:\kathir>FileCopy.exe

 

FILECOPY.EXE <source filename> <dest1 filename> <dest2 filename>]

 

Press any key to continue . . .

 

 

c:\kathir>FileCopy.exe c:\kathir.dat c:\kathir1.dat c:\kathir2.dat

 

c:\kathir.dat is copied to c:\kathir1.dat

c:\kathir1.dat is copied to c:\kathir2.dat

 

Press any key to continue . . .