2011-04-30 80 views
97

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

+3

的FSTAT功能的问题我相信是便携式的,而且很容易使用。 – ultifinitus 2011-04-30 07:09:33

+0

可能与http://stackoverflow.com/questions/2409504 – 2011-04-30 07:10:58

+13

dupicated为什么没有提升,但允许glib? Boost也是便携式的。 – rve 2011-04-30 07:14:45

回答

124
#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/

+0

为什么你需要'std :: ifstream :: in'这里?根本没有输入流。 – qed 2013-11-04 16:51:44

+31

更好的答案实际上是使用ios :: binary | ios :: ate代替。这将在最后以光标打开文件。所以你只需返回in.tellg()而不需要查找:) – jterm 2013-12-12 22:31:58

+3

或者只是从stat文件系统中获取它的大小已被维护。无需打开文件。 – Matt 2014-06-11 20:06:56

22

使用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; 
} 
+4

您不需要''和'',您确实需要'',您需要进行错误检查。 (使用NULL文件时'fseek'段错误,ftell在错误时返回-1) – rve 2011-04-30 16:48:04

+4

初始化p_file并在下一行覆盖它是没有意义的,并且使得许多lint抱怨“未使用的赋值”。 – Jens 2012-05-27 19:26:56

+0

你应该使用'long'作为返回类型吗? – Progo 2014-08-15 15:46:45

56

虽然不一定是最流行的方法,我听说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; 
} 

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

+2

上述代码可以移植到C&C++ – Matt 2013-12-04 22:45:34

+2

+1中提到以二进制模式打开流。这解决了我在使用read()时使用fseek()+ ftell()大小的问题。 – 2014-11-07 20:14:09

+3

我需要添加#包括和GetFileSize(...)适用于我。 – SyntheticGio 2017-01-26 18:40:34

2

在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; 
} 
+0

这是行不通的,你不能将tellg输出转换为int – 2018-01-25 10:29:29

+0

@StepanYakovenko看看这个网址http://www.cplusplus.com/reference/istream/istream/tellg/ – 2018-01-26 18:55:28

19

使用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"; 
} 
+3

值得注意的是'filesystem'是ISO C++的C++ 17 – chappjc 2016-12-10 02:17:47

+0

所以比tellg快吗? – 2018-03-07 02:11:16

1
#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); 

} 
-1

正好下面的代码片断解决了在此 交:)

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