【问题标题】:Using C++ filestreams (fstream), how can you determine the size of a file?使用 C++ 文件流 (fstream),如何确定文件的大小?
【发布时间】:2011-01-25 10:54:38
【问题描述】:

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

【问题讨论】:

标签: c++ filesize fstream istream


【解决方案1】:

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

ifstream file( "example.txt", ios::binary | ios::ate);
return file.tellg();

【讨论】:

【解决方案2】:

你可以一直寻找到最后,然后计算差值:

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;
}

【讨论】:

  • 出于兴趣,第一次调用tellg 不保证返回0?
  • 我想知道为什么在 21 世纪我们仍然需要手动计算流的大小?为什么委员会不为每个人都可以使用的功能创建一个功能?不就是这么简单吗?是否有任何隐藏的警告?
  • @rightaway717:他们可以。但为什么? C++ 不是一种“一切都为您完成”的语言。它提供了构建块,然后您可以对它们做任何您想做的事情。创建一个仅服务于这个特定用例的函数将完全浪费时间。此外,一个简单的“getter”很容易误导人们没有意识到涉及文件搜索,这可能在各种情况下对他们产生影响。最好让人们明确地这样做。
  • @LightnessRacesinOrbit:虽然我明白你的意思,但我仍然不同意。许多其他函数也是为特定用例提供服务的原始函数,例如获取字符串的长度。这是一个非常常见的操作,用于获取事物的大小以为其创建函数。我相信你在你的代码中也能做到这一点——提供一个函数来了解你自己的类的大小,如果大小对它们有意义的话。还有很多函数可以在引擎盖下进行(可能)长时间的操作,比如例如,矢量调整大小。这并不意味着我们必须让人们明确地去做。
  • @LightnessRacesinOrbit,在大多数系统上,通过减去由tell的操作返回的offests来获取文件大小比直接获取存储在inode或类似结构中的文件大小的操作要慢文件系统本身。因此,虽然后备算法可能是使用 seek's 和 tell's 的算法,但优化的实现可以解决这个问题并提供一种更快的方法。这有什么不好?
【解决方案3】:

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

来自stackoverflow的问题tellg() function give wrong size of file?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 );

【讨论】:

  • 我的...我想我会继续使用stat()
【解决方案4】:

像这样:

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;

【讨论】:

  • 您可能希望使用更合适的std::streampos 而不是long,因为后者可能不支持与前者一样大的范围 - 而streampos 不仅仅是一个整数。
  • 你的begin不就是0吗?
【解决方案5】:

我是新手,但这是我自学的做法:

ifstream input_file("example.txt", ios::in | ios::binary)

streambuf* buf_ptr =  input_file.rdbuf(); //pointer to the stream buffer

input.get(); //extract one char from the stream, to activate the buffer
input.unget(); //put the character back to undo the get()

size_t file_size = buf_ptr->in_avail();
//a value of 0 will be returned if the stream was not activated, per line 3.

【讨论】:

  • 所有这一切都是确定是否有第一个字符。这有什么帮助?
猜你喜欢
  • 1970-01-01
  • 2010-09-05
  • 2013-07-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
相关资源
最近更新 更多