Sidar
Sidar

Reputation: 544

C++ copying files. Short on data

I'm trying to copy a file, but whatever I try, the copy seems to be a few bytes short.

_file is an ifstream set to binary mode.

void FileProcessor::send()
{
    //If no file is opened return
    if(!_file.is_open()) return;
    //Reset position to beginning
    _file.seekg(0, ios::beg);

    //Result buffer
    char * buffer;
    char * partBytes = new char[_bufferSize];
    //Packet *p;
    //Read the file and send it over the network

    while(_file.read(partBytes,_bufferSize))
    {
        //buffer = Packet::create(Packet::FILE,std::string(partBytes));
        //p = Packet::create(buffer);
        //cout<< p->getLength() << "\n";
        //writeToFile(p->getData().c_str(),p->getLength());
        writeToFile(partBytes,_bufferSize);
        //delete[] buffer;
    }

    //cout<< *p << "\n";
    delete [] partBytes;
}

_writeFile is the file to be written to.

void FileProcessor::writeToFile(const char *buffer,unsigned int size)
{
    if(_writeFile.is_open())
    {
        _writeFile.write(buffer,size);
        _writeFile.flush();
    }
}

In this case I'm trying to copy a zip file. But opening both the original and copy in notepad I noticed that while they look identical , It's different at the end where the copy is missing a few bytes.

Any suggestions?

Upvotes: 1

Views: 337

Answers (4)

Cameron
Cameron

Reputation: 98756

You don't want to always do writeToFile(partBytes,_bufferSize); since it's possible (at the end) that less than _bufferSize bytes were read. Also, as pointed out in the comments on this answer, the ifstream is no longer "true" once the EOF is reached, so the last chunk isn't copied (this is your posted problem). Instead, use gcount() to get the number of bytes read:

do
{
    _file.read(partBytes, _bufferSize);
    writeToFile(partBytes, (unsigned int)_file.gcount());
} while (_file);

For comparisons of zip files, you might want to consider using a non-text editor to do the comparison; HxD is a great (free) hex editor with a file compare option.

Upvotes: 0

mfontanini
mfontanini

Reputation: 21900

You are assuming that the file's size is a multiple of _bufferSize. You have to check what's left on the buffer after the while:

while(_file.read(partBytes,_bufferSize)) {
  writeToFile(partBytes,_bufferSize);
}
if(_file.gcount())
    writeToFile(partBytes, _file.gcount());

Upvotes: 2

Martin McBride
Martin McBride

Reputation: 498

Your while loop will terminate when it fails to read _bufferSize bytes because it hits an EOF.

The final call to read() might have read some data (just not a full buffer) but your code ignores it.

After your loop you need to check _file.gcount() and if it is not zero, write those remaining bytes out.

Upvotes: 1

Steve Wellens
Steve Wellens

Reputation: 20620

Are you copying from one type of media to another? Perhaps different sector sizes are causing the apparent weirdness.

What if _bufferSize doesn't divide evenly into the size of the file...that might cause extra bytes to be written.

Upvotes: 0

Related Questions