6

我尝试使用 ifstream 读取一个 3GB 的数据文件,它给了我错误的文件大小,而当我读取一个 600MB 的文件时,它给了我正确的结果。除了错误的文件大小之外,我也无法使用 ifstream 读取整个文件。

这是我使用的代码

        std::wstring name;
        name.assign(fileName.begin(), fileName.end());
        __stat64 buf;
        if (_wstat64(name.c_str(), &buf) != 0)
            std::cout << -1; // error, could use errno to find out more

        std::cout << " Windows file size : " << buf.st_size << std::endl;;


        std::ifstream fs(fileName.c_str(), std::ifstream::in | std::ifstream::binary);
        fs.seekg(0, std::ios_base::end);

        std::cout << " ifstream  file size: " << fs.tellg() << std::endl;

3GB 文件的输出是

 Windows file size : 3147046042
 ifstream  file size: -1147921254

而 600 MB 文件的输出是

 Windows file size : 678761111
 ifstream  file size: 678761111

以防万一,我还测试了 5GB 文件和 300 MB 文件,

5GB 文件的输出是

Windows file size : 5430386900
 ifstream  file size: 1135419604

300MB 文件的输出是

Windows file size : 318763632
 ifstream  file size: 318763632

在我看来,它已经达到了某种极限。

我正在使用 Visual Studio 2010 在具有大量内存和磁盘空间的 Windows 机器上测试代码。

我正在尝试读取一些大文件。如果 ifstream 无法读取大文件,哪个是好的流阅读器?

4

3 回答 3

6

我想你想说:

std::cout << " ifstream  file size: " << fs.tellg().seekpos() << std::endl;

至少对于我放置的 6GB 文件来说,这可以正常工作。但我正在使用 Visual Studio 2012 进行编译。甚至您的原始代码在该环境下也可以正常工作。

所以我怀疑这是 VS 2010 上的 std 库中的一个错误,该错误已在 VS 2012 中得到修复。是否是 pos_type 的运算符重载中的一个错误,或者该类是否不支持 64 位是未知的。我必须安装 VS 2010 才能验证,但这可能是问题所在。

于 2013-05-01T19:30:14.143 回答
4

我稍微修改了您的代码,使其可以编译:

#include <fstream>
#include <iostream>
#include <string>
#include <windows.h>

int main() { 

    std::wstring name(L"whatever.txt");

    __stat64 buf;
    if (_wstat64(name.c_str(), &buf) != 0)
        std::cout << -1; // error, could use errno to find out more

    std::cout << " Windows file size : " << buf.st_size << std::endl;;


    std::ifstream fs(name.c_str(), std::ifstream::in | std::ifstream::binary);
    fs.seekg(0, std::ios_base::end);

    std::cout << " ifstream  file size: " << fs.tellg() << std::endl;

    return 0;
}

我在一个~3 GB 的文件上试过这个。使用 VS 2012(32 位或 64 位)它产生:

 Windows file size : 3581853696
 ifstream  file size: 3581853696

使用 32 位 VS 2008(抱歉,现在没有安装 VS 2010 的副本)我得到:

 Windows file size : 3581853696
 ifstream  file size: -713113600

因此,看起来旧版本的 VS/VC++ 使用 32 位有符号数来表示文件大小,因此它们对 iostreams 的实际限制可能是 2 GB。对于 VS 2012,这显然已得到纠正。

于 2013-05-01T19:44:35.413 回答
0

最大文件大小由编译器和操作系统决定。

编译器可以控制用于访问文件大小的变量的大小。

操作系统确定它可以支持的最大文件大小。

C++ 语言不限制文件大小。

示例 1:
编译器可以为文件位置变量分配 16 位,而操作系统可以使用 32 位指针作为最大文件大小。在这种情况下,编译器是限制因素。

示例 2:
编译器可以使用 32 位作为文件位置变量,但操作系统使用 24 位。在此示例中,操作系统是限制因素。

总之,最大文件大小取决于编译器和操作系统。

于 2013-05-01T19:32:16.983 回答