使用C++文件流(fstream),如何确定文件的大小?

war*_*ren 74 c++ fstream filesize istream

我确定我在手册中错过了这个,但是如何使用标题中的C++ istream类来确定文件的大小(以字节为单位)fstream

小智 85

您可以使用ios::ate标志(和ios::binary标志)打开文件,因此该tellg()函数将直接为您提供文件大小:

ifstream file( "example.txt", ios::binary | ios::ate);
return file.tellg();
Run Code Online (Sandbox Code Playgroud)

  • @Dominik Honnef:在VS 2013 Update5 64位这种方法,使用_ios:ate_ flag而没有_seekg(0,ios:end)_可能不适用于大文件.有关详细信息,请参阅http://stackoverflow.com/questions/32057750/how-to-get-the-filesize-for-large-files-in-c. (5认同)
  • 这似乎不是一个好方法.[tellg不报告文件的大小,也不报告从字节开头的偏移量](http://stackoverflow.com/a/22986486/1835769). (3认同)
  • @displayName [cplusplus.com](http://www.cplusplus.com/reference/istream/istream/seekg/) 有点不同意这个说法:它确实使用 `tellg()` 来检测文件大小。 (2认同)
  • 下面的答案适用于所有情况,而不适用于此情况,因为在很多情况下,当指针位于文件开头时,它返回0 (2认同)

Ara*_*raK 58

你可以寻找到最后,然后计算差异:

std::streampos fileSize( const char* filePath ){

    std::streampos fsize = 0;
    std::ifstream file( filePath, std::ios::binary );

    fsize = file.tellg();
    file.seekg( 0, std::ios::end );
    fsize = file.tellg() - fsize;
    file.close();

    return fsize;
}
Run Code Online (Sandbox Code Playgroud)

  • 我想知道为什么在21世纪我们仍然需要手动计算流的大小?为什么委员会不能为每个人都能使用的功能做出贡献?这不是那么简单吗?有任何隐藏的警告吗? (13认同)
  • 出于兴趣,第一次调用`tellg`不能保证返回0? (8认同)
  • @LightnessRacesinOrbit:虽然我明白你的意思,但我仍然不同意.许多其他函数也是为其特定用例提供服务的原始函数,比如获取字符串的长度.这是一个非常常见的操作,可以获得事物的大小来实现它的功能.我相信你也可以在你的代码中做到这一点 - 提供一个函数来了解你自己的类的大小,如果大小对它们有意义的话.还有很多函数可以做(可能)长时间操作,比如矢量调整大小例如.这并不意味着我们必须让人们明确地做到这一点. (7认同)
  • @LightnessRacesinOrbit:数十万开发人员从头开始减去并不是浪费时间...如果指针是实际字节位置,并且保证为 0,情况就会有所不同。此外,常见的 stat() 调用可以返回值 - 数据已经存在 - 而不执行任何查找。同时,我们可以访问 file.tellg(ios::begin) 值,但它完全没用;一段本身无用的底层数据,其唯一目的是允许开发人员将其与另一个底层值结合起来以提取有用的东西。 (3认同)
  • @LightnessRacesinOrbit,在大多数系统上通过减去tell的操作返回的offests来获取文件大小是一个比直接获取存储在文件系统本身的inode或类似结构中的文件大小更慢的操作.因此,虽然回退算法可能是使用搜索和告诉的算法,但优化的实现可以解决这个问题并提供更快的方法.怎么这是件坏事? (3认同)
  • @ rightaway717:他们可以.但为什么?C++不是"一切都为你完成"的语言.它提供了构建块,然后您可以随心所欲地执行任何操作.创建一个仅为这个特定用例提供服务的函数将完全浪费时间.此外,一个简单的"吸气剂"很容易误导人们没有意识到涉及文件搜索,这可能会在各种情况下对他们产生影响.让人们明确地做到这一点更好. (2认同)
  • 确实没关系,似乎健忘的就是你,在这里。 (2认同)

Job*_*bin 26

不要tellg用于确定文件的确切大小.确定的长度tellg将大于可从文件中读取的字符数.

从stackoverflow问题tellg()函数给出错误的文件大小? tellg不报告文件的大小,也不报告从字节开始的偏移量.它会报告一个令牌值,以后可以用它来寻找同一个地方,仅此而已.(甚至不能保证您可以将类型转换为整数类型.).对于Windows(以及大多数非Unix系统),在文本模式下,tellg返回的内容和必须读取到该位置的字节数之间没有直接和直接的映射.

如果确切地知道您可以读取多少字节很重要,那么可靠地执行此操作的唯一方法是阅读.您应该可以使用以下内容执行此操作:

#include <fstream>
#include <limits>

ifstream file;
file.open(name,std::ios::in|std::ios::binary);
file.ignore( std::numeric_limits<std::streamsize>::max() );
std::streamsize length = file.gcount();
file.clear();   //  Since ignore will have set eof.
file.seekg( 0, std::ios_base::beg );
Run Code Online (Sandbox Code Playgroud)

  • 我的...我想我会继续使用`stat()`。 (4认同)

Phi*_*lip 9

像这样:

long begin, end;
ifstream myfile ("example.txt");
begin = myfile.tellg();
myfile.seekg (0, ios::end);
end = myfile.tellg();
myfile.close();
cout << "size: " << (end-begin) << " bytes." << endl;
Run Code Online (Sandbox Code Playgroud)

  • 您可能希望使用更合适的`std :: streampos`而不是`long`,因为后者可能不支持与前者一样大的范围 - 而`streampos`*不仅仅是一个整数. (10认同)

alt*_*gel 9

从 C++17 开始,我们有了std::filesystem::file_size. 严格来说,这并不使用istreamor ,fstream但它是迄今为止在标准 C++ 中读取文件大小的最简洁、最正确的方法。

#include <filesystem>
...
auto size = std::filesystem::file_size("example.txt");
Run Code Online (Sandbox Code Playgroud)