Quick and Dirty Series: C++ FileSize() function






4.08/5 (20 votes)
Dec 9, 2004
2 min read

180875
Finding the size of the file in C++ in a portable manner is not trivial!
Introduction
The C++ standard library doesn't have a FileSize()
function, and in fact, there is no simple way to query the file size in a portable manner. To help others avoid the embarrassment of asking such a question on newsgroups, I decided to post a solution.
The reason is that the size of a file is only really accessible through the operating system. C++ was written to assume as little about the platform as possible, including whether or not there is an operating system with a file system. Yeah, I know, my reaction is the same as yours, but nonetheless, we must carry onward brave programmer, and get the job done.
Compiler Specific: Visual C++
The following contribution by Jesse Chisholm works very well if you will only ever be compiling with Visual C++:
#include <sys\types.h> #include <sys\stat.h> __int64 FileSize64( const char * szFileName ) { struct __stat64 fileStat; int err = _stat64( szFileName, &fileStat ); if (0 != err) return 0; return fileStat.st_size; }
Pitfalls:
- Specific to Visual C++.
Non-Portable Version: stat()
Many C++ compilers provide the C run-time function stat()
:
#include <sys\types.h> #include <sys\stat.h> int FileSize( const char * szFileName ) { struct stat fileStat; int err = stat( szFileName, &fileStat ); if (0 != err) return 0; return fileStat.st_size; }
Pitfalls:
stat()
isn't part of the C++ standard, so it may or may not be available.- The file size may be bigger than can be represented by an
int
. stat()
isn't necessarily precise.
Portable Version: ifstream::tellg()
The following is kind of a defacto standard I use, and which I have seen often, with variations:
#include <fstream> int FileSize(const char* sFileName) { std::ifstream f; f.open(sFileName, std::ios_base::binary | std::ios_base::in); if (!f.good() || f.eof() || !f.is_open()) { return 0; } f.seekg(0, std::ios_base::beg); std::ifstream::pos_type begin_pos = f.tellg(); f.seekg(0, std::ios_base::end); return static_cast<int>(f.tellg() - begin_pos); }
Pitfalls:
- The file size may be bigger than can be represented by an
int
. - The size of the file may be larger than what is reported.
If you can live with that, which I usually can, then great! Otherwise, there is another option.
Using Boost
There is a better solution, if you have the Boost C++ library installed which provides us with the following function:
#include <boost/filesystem/operations.hpp> boost::intmax_t file_size( const path & ph );
Pitfalls:
- You need to have Boost.
- If a compiler does not support
maxint_t
large enough to represent the operating system's maximum file size, the returned value could be incorrect.
More information on boost::file_size
is available here.
Summary
C++ is very hard to master. This is mainly because there are so many ways to do things, it can be hard to identify the best way (or the path of least evil, if you will). As a professional coder, sometimes good enough is in fact good enough, so I have decided to start a series of articles at CodeProject called the Quick and Dirty Series, for coders who need to get a job done, and wouldn't mind learning a thing or two along the way.
Acknowledgements
The following people helped out enormously by responding to my post on comp.lang.c++: Jonathan Turkanis, Siemel Naran, and Thomas Matthews. Jesse Chisholm supplied the Visual C++ version.