【问题标题】:How can I get a file's size in C++? [duplicate]如何在 C++ 中获取文件的大小? [复制]
【发布时间】:2011-08-15 22:59:23
【问题描述】:

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

【问题讨论】:

  • 为什么不提升但允许 glib? Boost 也是便携式的。
  • @mmutz:“便携”与“标准”的含义不同。例如,Boost 比标准 C++ 更具可移植性,因为它具有针对编译器不兼容(包括旧版本)的变通方法。 Fstat 在最严格的意义上是可移植的。
  • @Thomas:没有标准就没有“便携”。该标准可能采用书面文档的形式(如 POSIX 或 C++),并且您希望所有实现都忠实于它,或者它可能是通过已移植到许多平台(大多数库、包括升压)。 fstat() 在 POSIX 中是标准化的,但 Windows 选择通过调用函数 _fstat() 来偏离该标准。 fstat()可移植,因为您需要 #ifdef _WIN32 才能使用它。
  • 许多 boost 函数是可移植的,但需要显式编译。

标签: c++ filesize


【解决方案1】:
#include <fstream>

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

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

编辑:此答案不正确,因为 tellg() 不一定返回正确的值。见http://stackoverflow.com/a/22986486/1835769

【讨论】:

  • 根据@jterm 的建议,打开流是std::ifstream in(filename, std::ios::binary | std::ios::ate); 只是为了方便大家的生活;)
  • @WillingGood 文件将在函数返回后关闭。
  • 如上所述,我不认为 tellg() 可以保证返回大小,尽管它在我已经完成的 Linux 系统上总是对我有用(因此使用风险自负)。
  • 这是误导性答案,因为无法将 pos_type 转换为 int/long
【解决方案2】:

虽然不一定是最流行的方法,但我听说 ftell、fseek 方法在某些情况下可能并不总是给出准确的结果。具体来说,如果使用了一个已经打开的文件并且需要计算它的大小并且它恰好作为文本文件打开,那么它会给出错误的答案。

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

#include <sys/stat.h>

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

在某些系统上还有 stat64/fstat64。因此,如果您需要它来处理非常大的文件,您可能需要考虑使用这些文件。

【讨论】:

  • 以上代码可移植到 C 和 C++
  • +1 提到以二进制模式打开流。这解决了我在使用 fseek()+ftell() 大小和 read() 时遇到的问题。
  • 我需要添加 #include 并且 GetFileSize(...) 适合我。
  • 注意在 Visual Studio 中 long 是 4 字节,所以你必须使用 f.e. long long 以获得 Windows 上大文件的正确文件大小
【解决方案3】:

使用 C++ 文件系统库:

#include <filesystem>

int main(int argc, char *argv[]) {
  std::filesystem::path p{argv[1]};

  std::cout << "The size of " << p.u8string() << " is " <<
      std::filesystem::file_size(p) << " bytes.\n";
}

【讨论】:

  • 值得注意的是,filesystem 是 C++17 的 ISO C++
  • 那比tellg快吗?
  • 我们真的需要先规范化文件名吗?!
  • IMO 对此的最佳答案。
  • @MohamadElnaqeeb 刚刚在 g++8 上进行了基准测试;与 seekg 和 tellg 不同,它稍快且正确。
【解决方案4】:

也可以使用 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;
}

【讨论】:

  • 你不需要&lt;fstream&gt;&lt;iostream&gt;,你需要&lt;string&gt;并且你需要错误检查。 (fseek 使用 NULL 文件时的段错误,ftell 出错时返回 -1)
  • 初始化 p_file 并在下一行覆盖它是没有意义的,并且让许多 lint 抱怨“未使用的分配”。
  • " 允许库实现不支持 SEEK_END(因此,使用它的代码没有真正的标准可移植性)"
  • 这个答案具有误导性,应该被否决恕我直言:wiki.sei.cmu.edu/confluence/display/c/…
【解决方案5】:
#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);
}

【讨论】:

    【解决方案6】:

    在 c++ 中,您可以使用以下函数,它将返回文件的大小(以字节为单位)。

    #include <fstream>
    
    int fileSize(const char *add){
        ifstream mySource;
        mySource.open(add, ios_base::binary);
        mySource.seekg(0,ios_base::end);
        int size = mySource.tellg();
        mySource.close();
        return size;
    }
    

    【讨论】:

    【解决方案7】:

    下面的代码 sn-p 正好解决了这个问题 发布:)

    ///
    /// Get me my file size in bytes (long long to support any file size supported by your OS.
    ///
    long long Logger::getFileSize()
    {
        std::streampos fsize = 0;
    
        std::ifstream myfile ("myfile.txt", ios::in);  // File is of type const char*
    
        fsize = myfile.tellg();         // The file pointer is currently at the beginning
        myfile.seekg(0, ios::end);      // Place the file pointer at the end of file
    
        fsize = myfile.tellg() - fsize;
        myfile.close();
    
        static_assert(sizeof(fsize) >= sizeof(long long), "Oops.");
    
        cout << "size is: " << fsize << " bytes.\n";
        return fsize;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-28
      • 2012-08-23
      • 1970-01-01
      • 2010-11-25
      • 2023-01-11
      • 2011-09-29
      • 1970-01-01
      相关资源
      最近更新 更多