在 C++ 中写入并加载大型数组 to/from 文件

Writing and loading a large array to/from a file in C++

我正在创建一个大型二维数组 (5000*5000) 数据,稍后我需要在我的程序中使用这些数据。填充数组的过程需要 10 秒,但最后的数组数据总是相同的。所以,我想我可以通过每次 运行 我的程序时从文件读取数组来避免这 10 秒。

但是,我想不出将我的数组写入文件的有效方法。该数组由浮点数组成,所有浮点数之间都写有 space 甚至一行,我可以稍后轻松读取它们并重新创建数组。这显然是一个坏主意,因为我最终得到了一个数百万行的巨大 txt 文件。从那里读取需要更长的时间,并且文件占用了太多 space.

如何将数组保存到文件中以便稍后加载

编辑: 你建议我尝试以二进制格式保存。我发现的教程让我有些困惑。这是我的努力:

//2d array[size][size]
vec4** F = new vec4*[size];
for (int i = 0; i < size; i++) {
    F[i] = new vec4[size];
}
// Array is filling up, I won't include this part
//...........
// Array is ready.

//Trying to write the array in a file.
FILE* pFile;
pFile = fopen("myfile.bin", "wb");
fwrite(F, sizeof(vec4*), sizeof(F), pFile);

//Other method
std::ofstream out("filename.data", std::ios_base::binary);
out.write((char*)F, sizeof(vec4)*(size*size));

这两种方法都会创建空文件。也许它是一个二维数组这一事实使 fwrite 和 write 变得复杂?

简单地写出整个数组 as-is 的原始二进制形式,而不是文本形式。

vec4* F = new vec4[size*size];

// fill and use the array as needed...

std::ofstream out("filename.data", std::ios_base::binary);
out.write((char*)F, sizeof(vec4)*(size*size));

delete[] F;

然后您可以将文件读回数组 as-is:

vec4* F = new vec4[size*size];

std::ifstream in("filename.data", std::ios_base::binary);
if (!in.read((char*)F, sizeof(vec4)*(size*size)))
{
    // generate new values as needed...
}

// use the array as needed...

delete[] F;

或者,如果您使用 memory-mapped 文件(CreateFileMapping()/MapViewOfFile() on Windows,mmap() on Linux,等等) ,那么你甚至不必分配数组并将文件读入其中,你可以直接使用 memory-mapped 数据指针访问文件数据,例如:

vec4 *F = map the file ...; // <-- use platform-specific APIs for this!
bool mapped = (F != nullptr);
if (!mapped)
{
    F = new vec4[size*size];

    // generate new values as needed...

    std::ofstream out("filename.data", std::ios_base::binary);
    out.write((char*)F, sizeof(vec4)*(size*size));
}

// use the array as needed ...

if (mapped)
    unmap the file; // <-- use platform-specific APIs for this...
else
    delete[] F;

更新: 如果你想使用二维稀疏数组,你将不得不在你的文件 I/O 中以不同的方式考虑这一点,例如:

vec4** F = new vec4*[size];
for (int i = 0; i < size; ++i) {
    F[i] = new vec4[size];
}

{
    std::ifstream in("filename.data", std::ios_base::binary);
    if (in)
    {
        for (int i = 0; i < size; ++i) {
            in.read((char*)F[i], sizeof(vec4)*size);
        }
    }

    if (!in)
    {
        // generate new values as needed...
    }
}

// use the array as needed...

{
    std::ofstream out("filename.data", std::ios_base::binary);
    for (int i = 0; i < size; ++i) {
        out.write((char*)F[i], sizeof(vec4)*size);
    }
}

for (int i = 0; i < size; ++i) {
    delete[] F[i];
}
delete[] F;