Retrieving the size of a file using C++

I’ve googled and googled and I can’t seem to find any help :frowning:

I need a simple C++ (managed code) function that returns the size of a given file (ie: I’m passing a System::String with the file NAME, and I want to determine the size (in bytes) of that file).

Don’t worry about verifying if the file exists or any other kind of error handling… I just want something simple to return, in bytes, the size of a file whose filename is passed.

Thanks so much!

_filelength appears to be MS specific, which, seeing as you are using .NET, would suffice.
There’s also a way of moving the file pointer from the beginning to the end of a file and retrieving the dfference, which is the file size, using a C stdlib function which I’ve forgotten the name of.

Strictly speaking, C++ itself does not contain such a function. Most modern computer languages leave such mundane things to the operating system and they assume some library will exist that does things like I/O and whatnot.

But I might still be able to answer your question. Since you used the phrase, “(managed code)” I’m thinking that you’re talking about .NET. If so, you need to instantiate a FileInfo object and it’s Length property will contain the length of the file in bytes.

There is a way to do it that is portable across all systems. In C++:


int filelength(const char *filename)
{
  int result;
  ifstream file(filename);

  file.seekg(0, ios_base::end);
  result = file.tellg();
  file.close();

  return result;
}

In C, it would look like this:


long filelength(char *filename)
{
  long result;
  FILE *fp;

  fp = fopen(result, "rb");
  fseek(fp, 0L, SEEK_END);
  result = ftell(fp);
  fclose(fp);

  return result;
}

The above code segments are just off the top of my head, haven’t checked them for syntax errors, and I’m not checking to see if the file is actually therebut the actual code should look about the same. No warranties, expressed or implied, yada yada yada…

One last note — checking online it seems fstream.h has been deprecated in favor of fstream, so the syntax above might not be supported in future versions in favor of versions that use templates, but it is supposed to work in current versions. Perhaps someone with more knowledge of ISO C++98 could step in?

Hey, Punoqllads, that sounds pretty neat - I’ve been looking for a quick way to do that as well. If it works, I’m going to be a very happy woman.

I don’t have my man pages in front of me, but I believe the function you’re looking for is out of the standard C library, and is either “stat” or “fstat”. You open the file, you stat the file, you get a big struct full of useful information, such as file size.

-lv

Punoqllads, you need to take into account 16 bit (Windows and commercial Unixes) or 32 bit (Linux) wide characters in order to claim cross-platform compliance.

Since you’re using .NET, don’t worry about the C library or C++ library way to do it… no sense pulling in any more unmanaged code than you need to. As sengle said, you want the FileInfo class:


__int64 GetFileSize(System::String * filename)
{
    System::IO::FileInfo * fi = new System::IO::FileInfo(filename);
    return fi->Length;
}

Cerowyn, good point, but the OP asked for the number of bytes in the file, not the number of characters. For characters, you would just divide it by sizeof(char).

fstat is a UNIX system call. It’s not available to Windows.

Standard C++ would look like so:


include <fstream>

std::istream::pos_type filelength(const char *filename)
{
  std::ifstream file(filename);
  file.seekg(0, std::ios_base::end);
  return file.tellg();
}

No need to close the ifstream, as the destructor will do that automatically. The only real difference is the explicit use of the std:: qualifier. You can put


using namespace std;

in your code to automatically put everything in the std namespace in, but please don’t that for any non-toy programs.

Microsoft Managed C++, with the .NET framework, would probably look like Mr2001’s example above. I don’t know it, but it looks fine to me.

Thanks, guys. The solution I finally used was:

System::IO::FileInfo *fInfo = new FileInfo(dlgOpen->FileName);
txtSize->Text = fInfo->Length.ToString();

And to be completely anal-retentive with respect to the statement that it is portable across all systems, note that the ifstream method probably doesn’t give you the desired info on MacOS, because it probably only refers to the data fork of the file.

But you’re on Windows so you don’t care.

Sorry ntucker but you can’t possibly be more anal-retentive about this type of thing than the good folks over at comp.lang.c++.moderated. Here’s the definative answer regarding calculating cross-platform file sizes [link].

Note that tellg() will work on many platforms, but it isn’t guaranteed to. OTOH, here’s a terrible but nominally correct solution for counting the number of bytes readable from a file:



#include <fstream>
#include <iterator>

std::iterator_traits<std::istream_iterator<unsigned char> >::distance_type
filesize( std::string const & filename )
{
	std::ifstream sfile( filename.c_str() );
	return std::distance( std::istream_iterator<unsigned char>( sfile ), std::istream_iterator<unsigned char>() );
}


While the code is original, I saw the idea as a (nonserious) reply on clc++m

the problem with this code is that it reads the entire file; it’s algorithmic complexity is O(n)

Several cross-platform libraries have filesize utilities so if you’re using one of these libraries then that would be a good choice, also tellg is liable to work on many platforms but it’s good to be aware that it isn’t intended to (according to the C++ standard) and that it may stop working. If it does stop working there are platform specific solutions for every platform you would use.

Not only is it available with Microsoft C/C++, but they provide a 64-bit version as well.

If anyone had any doubt that C++ is a product of a committee populated by denizens of Computer Hell you have but to look at np_complete’s code example.

Not that there’s anything wrong with that.

Thank you Punoqllads, I aim to provide pedantic and correct information with as little use as possible. That little example still isn’t the worst I’ve written (or read), unfortunately it’s only an example. I save my truly devious code for production work.

Punoqllads: If you think that’s bad, just wait until you have a typo in one of those lines, and you get a 25 line syntax error that refers to iterator.hpp and contains 500 colons and angle brackets. :wink:

Well damn, you’re right.

What got me is that I thought that Microsoft didn’t use the sys/ directory includes. A quick check finds out, that they in fact use it only for the stat functions and the ftime functions.

Learned something I did yes hrm.