172

Let's create a complementary question to this one. What is the most common way to get the file size in C++? Before answering, make sure it is portable (may be executed on Unix, Mac and Windows), reliable, easy to understand and without library dependencies (no boost or qt, but for instance glib is ok since it is portable library).

6
  • 1
    May dupicated with stackoverflow.com/questions/2409504 Commented Apr 30, 2011 at 7:10
  • 14
    Why no boost but allow glib? Boost is also portable. Commented Apr 30, 2011 at 7:14
  • 3
    @mmutz: "Portable" has a different meaning than "standard". For example, Boost is more portable than standard C++ because it has workarounds for non-compliancies of compilers (including older versions). Fstat is portable in the strictest sense. Commented Apr 30, 2011 at 23:44
  • 1
    @Thomas: There can be no "portable" without a standard. That standard may be in the form of a written document (like POSIX, or C++) and you hope that all implementations are true to it, or it may be by way of a common implementation that has been ported to many platforms (most libraries, incl. Boost). fstat() is standardized in POSIX, but Windows chose to deviate from that standard by calling the funciton _fstat(). fstat() is not portable, because you need an #ifdef _WIN32 to use it. Commented May 1, 2011 at 6:39
  • Lots of boost functions are portable but needs to compile explicitly. Commented Jun 12, 2015 at 3:42

7 Answers 7

174
#include <fstream> std::ifstream::pos_type filesize(const char* filename) { std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary); return in.tellg(); } 

See http://www.cplusplus.com/doc/tutorial/files/ for more information on files in C++.

edit: this answer is not correct since tellg() does not necessarily return the right value. See http://stackoverflow.com/a/22986486/1835769

Sign up to request clarification or add additional context in comments.

15 Comments

Based on @jterm suggestion, opening the stream would be std::ifstream in(filename, std::ios::binary | std::ios::ate); Just to ease everybody's life ;)
@WillingGood the file will be closed after returning of the function.
As mentioned above I don't think tellg() is guaranteed to return size, although it always has for me on linux systems I've done it on (so use at your own risk).
this is missleading answer, since there is no way to convert pos_type to int/long
|
135

Using the C++ filesystem library:

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

5 Comments

worth noting that filesystem is ISO C++ as of C++17
so is that faster than tellg?
Do we really need to canonicalize the filename first?!
@MohamadElnaqeeb just benchmarked this on g++8; it is slightly faster and it is correct, unlike seekg and tellg.
Always read StackOverflow pages from the bottom up!
118

While not necessarily the most popular method, I've heard that the ftell, fseek method may not always give accurate results in some circumstances. Specifically, if an already opened file is used and the size needs to be worked out on that and it happens to be opened as a text file, then it's going to give out wrong answers.

The following methods should always work as stat is part of the c runtime library on Windows, Mac and Linux.

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

If you need this for very large files (>2GB) you may want to look at calling stat64 and fstat64 if available.

5 Comments

The above code is portable to both C & C++
+1 For the mention of opening the stream in binary mode. That fixed an issue I was having using the fseek()+ftell() size with read().
I needed to add #include <sys/stat.h> and GetFileSize(...) works for me.
be aware of the fact that long is 4 byte in Visual Studio, so you have to use f.e. long long to get correct file size for big files on Windows
this approach works for files <2GBs
30

It is also possible to find that out using the fopen(),fseek() and ftell() function.

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

7 Comments

You do not need <fstream> and <iostream>, you do need <string> and you need error checking. (fseek segfaults when using a NULL file, ftell returns -1 on error)
Initializing p_file and overwriting it in the next line is pointless and and makes many lints complain about "unused assignment".
" Library implementations are allowed to not meaningfully support SEEK_END (therefore, code using it has no real standard portability)"
This answer is missleading and should be downvoted imho:wiki.sei.cmu.edu/confluence/display/c/…
|
9
#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 Comment

Extra points for not getting completely sucked into the idea that it has to be done with modern constructs.
1

In c++ you can use following function, it will return the size of you file in bytes.

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

3 Comments

this wouldn't work, you can't convert tellg output to int
@StepanYakovenko take a look at this url cplusplus.com/reference/istream/istream/tellg
@HadiRasekh please stop using cplusplus.com for C++ reference, it's outdated beyond usability. Not only it lacks the newer stuff from C++14, C++17, C++20 and experimental TS, it also has some considerable errors in some articles.
1

The code snippet below exactly addresses the question in this post :)

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.