У меня есть старый код, который записывает файлы составных блоков, которые очень медленно записываются в файл из-за интенсивного использования tellp и seekp, которые уничтожают все буферы.
Это работает так (псевдокод) :
WriteFile()
{
ostream ofStream = GetStream(strBlockFileName);
WriteFileHeader(ofStream);
// Write a directory
WriteDirStart(ofStream);
auto realItemInfo = WriteAllData(ofStream); // Write all data to the file
UpdateDirOnClose(ofStream, realItemInfo);
// Write next directory
WriteDirStart(ofStream);
auto realItemInfo = WriteAllData(ofStream);
UpdateDirOnClose(ofStream, realItemInfo);
// Write third directory
...
ofStrem.close();
}
WriteAllData(...)
{
for (auto& rItem : allItems)
{
rItem.Write(ofStream); // Also a bit slow since it writes just small data chunks
}
}
WriteDirStart(...)
{
// Write directory in compound file
startPos = ofStream.tellp(); // Save the start position of the directory
WriteStartPos(ofStream, startPos);
// Write dummy info to reserv the correct space
WriteDummyNumIntemInfo(ofStream, numItems);
WriteDummyDirectoryEndPos(ofStream, startPos);
}
UpdateDirOnClose(...)
{
// This is the slow part when updating the header at the end when the information
// is known due to changing positions in the file stream.
auto pos = ofStream.tellp();
ofStream.seekp(startPos); // Change to beginning of the directory
WriteStartPos(ofStream, startPos);
WriteRealNumIntemInfo(ofStream, realItemInfo);
WriteRealDirectoryEndPos(ofStream, pos);
ofStream.seekp(pos); // Change back so next directory can continue to write at correct position
}
Я подумал, можно ли записать каждый "каталог" из потока в буфер памяти, а затем записать весь буфер в файл, так как я предполагаю, что tellp и seekp не будут такими плохими влияние на буфер памяти. Итак, если есть какой-то байтовый буфер, который растет, может быть, как stringstream, или если есть что-то более эффективное, совместимое с ofstream.
Есть ли у вас какие-либо предложения, как это реализовать (или использовать что-то существующее, например, boost) или другие предложения, чтобы ускорить процесс? 70% времени тратится на seekp при обновлении заголовка каталога.
(Для чтения я "решил" это, используя файлы с отображением в память, так как при чтении как ну, но я не могу этого сделать для записи, поскольку размер заранее не известен. Это старый формат файла, поэтому я не могу многое сделать с файловой структурой.)
Все идеи приветствуются!