我需要打开一个现有的文件,然后将写到该文件的任意位置。也位于可能大于当前文件大小的位置。
每次调用写操作时,用"ab"打开文件时,都会将位置指示符设置为文件的末尾,这样就不能工作了。
使用"w+b"或"wb"打开文件将导致文件多次被写入(复制?)。文件大小从0开始有几次--这需要很长时间。参见执行以下测试时发生的情况的视频(1 run):http://screencast.com/t/Uj5ymikZUYJ
BOOST_AUTO_TEST_CASE(FileWriteTest_W_PLUS_B) {
auto started = chrono::high_resolution_clock::now();
FILE *filePointer = nullptr;
auto tmpFilename = string("C:\\temp\\") + boost::uuids::to_string(boost::uuids::random_generator()());
auto bufferSize = 1024 * 1024;
unique_ptr<unsigned char[]> buffer(new unsigned char[bufferSize]);
RAND_bytes(buffer.get(), bufferSize);
for (long long i = 0; i < 5; i++) {
//Open file
int openError = fopen_s(&filePointer, tmpFilename.c_str(), "w+b");
if (openError != 0)
BOOST_FAIL(string("Failed to open file ") + tmpFilename);
auto CurrentPosition = 1024LL * 1024LL * 1024LL * i;
//Set position to 0/1/2/3/4 GB
fsetpos(filePointer, &CurrentPosition);
//Write 1 GB of data at current position
for (int n = 0; n < 1024; n++) {
int written = fwrite(buffer.get(), sizeof(unsigned char), bufferSize, filePointer);
if (written != bufferSize) {
BOOST_FAIL(string("Unable to write ") + to_string(bufferSize) + string(" to file ") + tmpFilename + string(" at position ") + to_string(CurrentPosition));
}
}
//Close file
fclose(filePointer);
}
auto ended = chrono::high_resolution_clock::now();
cout << "Time :" << duration_cast<duration<double>>(ended - started).count() << " seconds";
}因此,我的问题是:是否有任何方法打开现有文件并将其写入任意位置(也位于比当前大小更大的位置)--而不像我目前使用"wb" / "w+b"所看到的那样受到性能损失?
还是我必须使文件的最终大小--当我第一次给它写信时?(例如,Torrent客户似乎是这样做的)。
fstreams由于其糟糕的I/O性能而不是一个选项。(见writing-a-binary-file-in-c-very-fast)
发布于 2016-08-22 13:37:16
您应该以"r+b"模式打开流。"w"模式导致文件被截断。如果文件不存在,则必须首先使用"wb"创建该文件。
但是,请注意,fsetpos()可能无法在文件结束后设置当前位置。如果需要,您应该检查返回值并将文件放置到目标位置。
要使位置具有字节偏移的意义,流还必须在二进制模式下使用b打开。默认情况下,流更多地以文本形式打开,在某些系统(如Windows )中,这可能会阻止正确的偏移管理。
https://stackoverflow.com/questions/39080952
复制相似问题