我正在尝试复制一个文件,但无论我尝试什么,副本似乎只有几个字节。
_file是ifstream设置为二进制模式。
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是要写入的文件。
void FileProcessor::writeToFile(const char *buffer,unsigned int size)
{
if(_writeFile.is_open())
{
_writeFile.write(buffer,size);
_writeFile.flush();
}
}
在这种情况下,我正在尝试复制一个zip文件。 但是在记事本中打开原件和副本时,我注意到虽然它们看起来相同,但是在副本缺少几个字节的末尾它是不同的。
有什么建议吗?
答案 0 :(得分:2)
您假设文件的大小是_bufferSize
的倍数。您必须在>>之后检查缓冲区上剩下的内容:
while(_file.read(partBytes,_bufferSize)) {
writeToFile(partBytes,_bufferSize);
}
if(_file.gcount())
writeToFile(partBytes, _file.gcount());
答案 1 :(得分:1)
你的while循环将在它无法读取_bufferSize字节时终止,因为它会触及EOF。
对read()的最后调用可能已经读取了一些数据(只是不是一个完整的缓冲区),但是你的代码忽略了它。
在循环之后,你需要检查_file.gcount(),如果它不是零,则将剩余的字节写出来。
答案 2 :(得分:0)
您不希望始终执行writeToFile(partBytes,_bufferSize);
,因为可能(最后)读取的_bufferSize
字节少于ifstream
。此外,正如对此答案的评论中所指出的,一旦达到EOF,gcount()
就不再是“真”,因此不会复制最后一个块(这是您发布的问题)。相反,使用do
{
_file.read(partBytes, _bufferSize);
writeToFile(partBytes, (unsigned int)_file.gcount());
} while (_file);
来获取读取的字节数:
{{1}}
对于zip文件的比较,您可能需要考虑使用非文本编辑器进行比较; HxD是一个很棒的(免费)十六进制编辑器,带有文件比较选项。
答案 3 :(得分:0)
您是从一种媒体复制到另一种媒体吗?也许不同的行业规模导致了明显的怪异。
如果_bufferSize没有均匀分配到文件的大小......可能会导致额外的字节写入。