保存大量的数字矢量到硬盘驱动器

Save large vector of numbers to hard disk drive

本文关键字:硬盘驱动器 保存 数字      更新时间:2023-10-16

我使用类型为unsigned short的向量在RAM中分配了一大块连续字节。

vector<unsigned short> testDump(204800000);
for(int k = 0; k<204800000; k++)
    testDump[k] = 9; \ This is different in my real program

现在我想把这个矢量保存到硬盘驱动器中。最快的方法是什么?怎么做?数据的大小相当大(~1/2 GB)。我尝试了以下操作:

ofstream outfile("allMyNumbers.txt", ios::out | ios::binary);
outfile.write(&testDump[0], testDump.size());

但是我得到以下错误:

cannot convert parameter 1 from 'unsigned short *' to 'const char *'

什么是最快的方式来完成我的任务,这是保存矢量文件使用最快的方法?

可以直接转换指针。

outfile.write(reinterpret_cast<char*>(&testDump[0]), testDump.size() * sizeof(unsigned short));

请注意,结果文件的格式是特定于您的特定平台/实现的。因此,在不兼容的机器上,您不一定能以明显的方式读取它。

在Windows上,这将给你一个400mb左右的文件,204800000对字节中的每一对代表一个小端无符号短文件。

这应该相当快。我很难相信你的任务真的是"用最快的方法"保存数据。人们怎么知道你的代码真的是最优的,不存在比你快一纳秒的代码呢?那么,为了缩短一纳秒而付出额外的努力又有什么意义呢?等等......

当然,使用快速流压缩算法来减少所需的磁盘空间可能更快,因为操作可能受到磁盘I/O的约束。但是代码会复杂得多,它是否有用取决于数据的可压缩性。

一种与平台无关的技术是使用ostream_iterator作为向量类的类型。因为你的向量包含的类型已经重载了operator<<ostream类类型,你不应该有任何问题实例化ostream_iterator类的模板为你的向量类型。然后,将STL中的ostream_iteratorcopy算法结合起来,遍历向量,并将原始字节序列化到文件中。使用operator<<将比使用ofstream::write消耗更多的数据,后者将原始二进制数据写入磁盘,但具有序列化数据的优点,使其在任何平台上都可以独立读取。

例如:

vector<unsigned short> testDump(2048000000);
//...fill in your vector
ofstream outfile("allMyNumbers.txt", ios::out | ios::binary);
//tab-delinate the data
ostream_iterator<unsigned short> o_iter(outfile, "t");
copy(testDump.begin(), testDump.end(), o_iter);

序列化它的跨平台方法是只关注short的小端序表示并转储所有的short。这将避免Jason的解决方案中的ASCII数据膨胀,同时是跨平台的。

因此,我将写入

ofstream outfile("allMyNumbers.data", ios::out | ios::binary);
for(int k = 0; k < testDump.size(); k++)
{
    unsigned short leData = htole16(testDump[k]);    
    outfile.write(&leData, sizeof(leData));
}

htole16 (host to little endian for 16位整数)的实现如下:

对于x86, x64:

unsigned short htole16(unsigned short x)
{
    return x;
}

对于像Sparc/PowerPC这样的大端机器(尽管这些都不能运行Windows 7)

unsigned short htole16(unsigned short x)
{
    return _byteswap_ushort(x);
}