我有一个函数可以实时计算所需的结果(最终结果是大约50MB的只包含字符的文本文件),但顺序相反。
举例说明:我的函数将计算“5,4,3,2,1,。。。”,但我要求将“1,2,3,4,5”写入文件。
我想把它写到一个输出文件中,从头到尾都是动态的。
目前,我正在使用std::ofstream::binary
缓冲,反转和写入文件,但是我需要减少相关的时间,更重要的是减少空间开销。
做这件事最有效率的方法是什么?
谢谢。
编辑:输出大小已知。
我明白你的要求是这样的:
如果您确实不想使用缓冲区,那么您必须使用seekp
。 但现在已经有一些暗示:这将是一个非常缓慢的解决方案。
反正怎么办? 所以:
Seek和write将如下所示
fileStream.seekp(offset--).put(testData[index]);
由于我没有你的计算功能,所以我创建了一些虚拟数据。 这需要你去适应。
请参阅以下示例片段:
#include <iostream>
#include <fstream>
#include <array>
#include <numeric>
// The known size of test data
constexpr size_t OutputSize = 50'000U;
// Some simple test data
static std::array<char, OutputSize> testData{};
int main() {
// You will calculate the data in a different part of your code
// I jsut fill the array with some data
std::iota(testData.begin(), testData.end(), 0);
// Open the file and check, if it could be opened.
if (std::ofstream fileStream{ "r:\\test.bin", std::ofstream::binary }; fileStream) {
// Caculate position offset of last element
size_t offset{ (OutputSize - 1)};
// Calculate and write data
for (size_t index{}; index < OutputSize; ++index) {
// Your claculation here
// . . .
// Seek and write data
fileStream.seekp(offset--).put(testData[index]);
}
}
return 0;
}
再来一次。 寻找是非常缓慢的。
实际上,从头到尾写文件是一个低效的解决方案,因为你会在文件预分配和查找上浪费一些时间。 最好只是从结束到开始再到文件写入数组。
我不知道你的程序是怎么写的,所以我的答案可能不是你想要的那么准确,但我假设它可以是这样做的:
#include <iostream>
#include <vector>
#include <ostream>
#include <fstream>
// Variant 1
void writeMyData(const std::vector<int>& data, std::ofstream& stream)
{
for (auto it = data.rbegin(); it != data.rend(); it++)
stream.write((const char*)&*it, sizeof(int));
}
// Variant 2
void writeMyData2(const int* data, int length, std::ofstream& stream)
{
for (int i = length - 1; i >= 0; i--)
stream.write((const char*)(data + i), sizeof(int));
}
int main()
{
std::vector<int> yourBuffer = {5, 4, 3, 2, 1};
std::ofstream file;
file.open ("data.bin", std::ios::binary);
// Write: 1, 2, 3, 4, 5
// Variant 1
writeMyData(yourBuffer, file);
// Variant 2
//writeMyData2(yourBuffer.data(), yourBuffer.size(), file);
file.close();
return 0;
}
因此,您可以使用反向迭代器(RBEGIN
,REND
而不是BEGIN
,END
)或仅以相反的顺序迭代循环。
更新:或者你可以在RAM中反转数据,然后一次性写入所有数据。 很可能,这将是最有效的方式。
std::reverse(std::begin(yourBuffer), std::end(yourBuffer));
stream.write((const char*)yourBuffer.data(), sizeof(int) * yourBuffer.size());
注意sizeof(int)
-可能您有char
或其他类型。