如何在C++中获取文件大小?

Sop*_*ner 123 c++ filesize

让我们为这个问题创建一个补充问题.在C++中获取文件大小的最常用方法是什么?在回答之前,确保它是可移植的(可以在Unix,Mac和Windows上执行),可靠,易于理解且没有库依赖(没有boost或qt,但是例如glib是可以的,因为它是可移植的库).

Spy*_*ros 151

#include <fstream>

std::ifstream::pos_type filesize(const char* filename)
{
    std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
    return in.tellg(); 
}
Run Code Online (Sandbox Code Playgroud)

有关C++文件的更多信息,请参见http://www.cplusplus.com/doc/tutorial/files/.

  • 这个关于SO的问题的答案说[tellg不会报告文件的大小,也不会报告从字节开头的偏移量.](http://stackoverflow.com/a/22986486/1835769) (16认同)
  • 基于@jterm建议,打开流将是`std :: ifstream in(filename,std :: ios :: binary | std :: ios :: ate);`只是为了让每个人的生活更轻松;) (10认同)
  • 这是一个具有误导性的答案,因为没有办法将pos_type转换为int/long (7认同)
  • @WillingGood文件将在返回函数后关闭. (4认同)
  • 如上所述,我不认为tellg()可以保证返回大小,虽然它总是在Linux系统上为我完成它(所以使用风险自负). (4认同)
  • 或者只是从文件系统中获取它,其中stat已经保持了大小.甚至不需要打开文件. (3认同)
  • 如何从tellg()获取文件大小??? (3认同)
  • 你不需要关闭文件吗? (2认同)

Mat*_*att 70

虽然不一定是最流行的方法,但我听说ftell,fseek方法在某些情况下可能并不总能给出准确的结果.具体来说,如果使用已经打开的文件并且需要对其进行处理并且它恰好作为文本文件打开,那么它将给出错误的答案.

以下方法应始终有效,因为stat是Windows,Mac和Linux上c运行时库的一部分.

long GetFileSize(std::string filename)
{
    struct stat stat_buf;
    int rc = stat(filename.c_str(), &stat_buf);
    return rc == 0 ? stat_buf.st_size : -1;
}

or 

long FdGetFileSize(int fd)
{
    struct stat stat_buf;
    int rc = fstat(fd, &stat_buf);
    return rc == 0 ? stat_buf.st_size : -1;
}
Run Code Online (Sandbox Code Playgroud)

在某些系统上还有一个stat64/fstat64.因此,如果你需要这个非常大的文件,你可能想看看使用它们.

  • 我需要添加#include <sys/stat.h>和GetFileSize(...)为我工作. (7认同)
  • 上面的代码可以同时移植到C&C++ (3认同)
  • +1提到以二进制模式打开流.这解决了我使用带有read()的fseek()+ ftell()大小的问题. (3认同)
  • 请注意,在 Visual Studio 中 long 为 4 字节,因此您必须使用 fe long long 来为 Windows 上的大文件获取正确的文件大小 (3认同)

bam*_*s53 28

使用C++文件系统TS:

#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;

int main(int argc, char *argv[]) {
  fs::path p{argv[1]};
  p = fs::canonical(p);

  std::cout << "The size of " << p.u8string() << " is " <<
      fs::file_size(p) << " bytes.\n";
}
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是`filesystem`是从C++ 17开始的ISO C++ (6认同)
  • 那么这比tellg 快吗? (3认同)
  • 我们真的需要先规范化文件名吗?! (3认同)
  • @MohamadElnaqeeb 刚刚在 g++8 上对此进行了基准测试;与eekg和tellg不同,它稍微快一点并且正确。 (2认同)

And*_*dro 24

也可以使用fopen(),fseek()和ftell()函数找到它.

int get_file_size(std::string filename) // path to file
{
    FILE *p_file = NULL;
    p_file = fopen(filename.c_str(),"rb");
    fseek(p_file,0,SEEK_END);
    int size = ftell(p_file);
    fclose(p_file);
    return size;
}
Run Code Online (Sandbox Code Playgroud)

  • 你不需要`<fstream>`和`<iostream>`,你需要`<string>`,你需要进行错误检查.(`fseek`使用NULL文件时段错误,错误时ftell返回-1) (4认同)
  • 初始化p_file并在下一行中覆盖它是没有意义的,并且许多lint抱怨"未使用的赋值". (4认同)
  • "允许库实现无意义地支持SEEK_END(因此,使用它的代码没有真正的标准可移植性)" (4认同)
  • 这个答案具有误导性,应该被否决:https://wiki.sei.cmu.edu/confluence/display/c/FIO19-C.+Do+not+use+fseek%28%29+and+ftell%28 %29+计算+a+常规+文件的+大小 (2认同)

小智 7

#include <stdio.h>
int main()
{
    FILE *f;
    f = fopen("mainfinal.c" , "r");
    fseek(f, 0, SEEK_END);
    unsigned long len = (unsigned long)ftell(f);
    printf("%ld\n", len);
    fclose(f);
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

241097 次

最近记录:

6 年,5 月 前