Search code examples
c++splitfstream

Split a File and put it back together in c++


I want to copy a file by reading blocks of data, sending it and than put it back together again. Sending is not part of the problem, so I left it out in the code. It should work with any type of file and arbitrary piece_lengths.

This is just a pre-stage. In the end data block should not be chosen sequentially but at random. There could be some time between receiving another block of data.

I know the example just makes sense if size % piece_length != 0.

I'm getting crashed files of the same size as the original file at the other end. Does anyone see the problem?

int main ()
{
string file = "path/test.txt"
string file2 = "path2/test.txt";

std::ifstream infile (file.c_str() ,std::ifstream::binary);
//get size of file
infile.seekg (0,infile.end);
long size = infile.tellg();
infile.seekg (0);   
size_t piece_length = 5;



for (int i = 0; i < ((size / piece_length) + 1); i++)
{
    if ( i != (size / piece_length))
    {
        std::ifstream infile (file.c_str() ,std::ifstream::binary);
        infile.seekg((i * piece_length) , infile.beg);          
        char* buffer = new char[piece_length];
        infile.read(buffer, piece_length);
        infile.close();
        std::ofstream outfile (file2.c_str() ,std::ofstream::binary);
        outfile.seekp((i * piece_length), outfile.beg);
        outfile.write(buffer, piece_length);
        outfile.close();
    }
    else 
    {
        std::ifstream infile (file.c_str() ,std::ifstream::binary);
        infile.seekg((i * piece_length) , infile.beg);          
        char* buffer = new char[size % piece_length];
        infile.read(buffer, size % piece_length);
        infile.close();
        std::ofstream outfile (file2.c_str() ,std::ofstream::binary);
        outfile.seekp((i * piece_length), outfile.beg);
        outfile.write(buffer, size % piece_length);
        outfile.close();
        }
}
return 0;
}

Solution

  • To answer your specific question, you need to open outfile with ios::in | ios::out in the flags, otherwise it defaults to write-only mode and destroys what was already in the file. See this answer for more details: Write to the middle of an existing binary file c++

    You may want to consider the following though:

    • If you are just writing parts to the end of the file, just use ios::app (append). Don't even need to seek.
    • You don't need to keep reopening infile or even outfile, just reuse them.
    • You can also reuse buffer. Please remember to delete them, or better yet use a std::vector.