2007年9月19日星期三

C++ FileSize() function

C++ FileSize() function
By Christopher Diggins.

Finding the size of the file in C++ in a portable manner is not trivial!
C++
Windows
MFC, Win32, VS
Dev
Posted: 9 Dec 2004
Updated: 15 Dec 2004
Views: 48,158
Announcements


Search
Advanced Search
Sitemap
PrintBroken Article?Bookmark Discuss Send to a friend
20 votes for this article.
Popularity: 4.59. Rating: 3.53 out of 5.
  • You are signed up for one or more newsletters but unfortunately we are unable to send you emails. Please click here to have an email sent that will allow us to confirm your email address.

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  
#include
__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  
#include
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 
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::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.

没有评论: