tutorials.neonphog.com icon

c++ - MyCopy - C++ Style

Introduction Get the Source Compiling and Running It Walkthrough Conclusion

Introduction

The standard stream classes are fairly adept at sending and receiving formatted information. Sometimes, however, we need to transfer large amounts of raw data. In a case like that, the stream classes fall back to a more C-Style method, even using a character buffer to store the data. Here is how it is done.

Get the Source

mycopy_cpp.h [view]

mycopy_cpp.cpp [view]

Compiling and Running It

1) Compile

Compile the source code with the following commands:

g++ -c -o mycopy_cpp.o mycopy_cpp.cpp
g++ -o mycopy_cpp mycopy_cpp.o

2) Run It

The way to run this file (as it should tell you if you run it without arguments) is to give it first the source file to copy from, then the filename to copy to.

Assuming you have a file "test.txt" (and you have permission to write to a new file in this directory) you should see output like the following:

$ ./mycopy_cpp test.txt newfile.txt
Copying test.txt to newfile.txt.
$

Walkthrough

1) Includes

#include <iostream>
#include <fstream>

We include "iostream" so that we can send messages to the user. "fstream" contains the "fstream" class that we will be using to do our file access.

2) Buffer Size

#define BUFSIZE (1024)
We set this to 1 KiB because it is a decently large size that shouldn't slow down our reading by doing lots of little calls.

We will need a memory buffer to hold data as we are transferring it between the files. This preprocessor definition will hold the size of this buffer for use later in our code.

3) The "mycopy_cpp" function

Now let us skip down to the actual work-horse function: mycopy_cpp

void mycopy_cpp( const char *sSrc, const char *sDest )

We will take two character strings, the first representing the source filename, and the second, the destination.

4) Our Memory Buffer

	char buf[BUFSIZE];

This is our memory buffer. Note the size of it is defined by "BUFSIZE".

5) Getting access to the files

	fstream fIn( sSrc, ios::binary|ios::in );
	fstream fOut( sDest, ios::binary|ios::out );
We should make sure that these files were actually open by checking fIn.is_open() and fOut.is_open(), and throw an exception if they are not. That, however, is beyond the scope of this tutorial.

We create two file streams, one with our source filename and "ios::in" telling it to read from that file, and one with our destination filename and "ios::out" telling it to write to that file. The "ios::binary" ensures that all systems will read and write the data exactly, without altering end-of-line characters, etc.

6) The actual copy

	while( fIn.good() )
	{
		fIn.read( buf, BUFSIZE );
		fOut.write( buf, fIn.gcount() );
	}
If you look at the C-Style version of this tutorial, you may notice some similarities in this section of code.

We loop while our input file stream is still capable of reading (fIn.good()). "fIn.read" will read up to "BUFSIZE" characters into our memory buffer. We then write those characters straight to fOut, our destination file stream. Note that the amount of characters we write is "fIn.gcount()". "gcount()" returns the number of characters that were actually read in the last read operation.

7) Cleaning Up

	fIn.close();
	fOut.close();

Just to be sure, we want to close our file streams to make sure they flush all their data.

Conclusion

You should now be able to read and write binary file data with the fstream class in the standard library.

tutorials home c++ home