Ryan's District Boards

Computer, programming, and webmaster help , support , tips and tricks => Tutorials Zone! => Internet webmaster computer programming technology tips and tricks => C++ / C / C# ....Tutorials => Topic started by: ben2ong2 on October 06, 2006, 11:26:55 PM

Title: C++ Tips: IO - portably checking file lengths
Post by: ben2ong2 on October 06, 2006, 11:26:55 PM
(Newsgroups: comp.lang.c++, 22 Mar 2000)

ED: ed@ftt.vsu.ru

> How can I get binary file length under HP Unix?

KUEHL: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>

Using portable C++ functions it basically comes down to using something
like this:

  std::ifstream in(filename, std::ios_base::binary);
  std::cout << "file size: " <<
    std::distance(std::istreambuf_iterator<char>(in),
                  std::istreambuf_iterator<char>());

Yes, unless 'distance()' is specialized for 'std::istreambuf_iterator'
this will read the file and basically count the number of characters.
There are other approaches how the same effect can be achieved but this
is the only portable approach.

On most machines it is possible to determine the file size using some
system call. These are, however, out of the scope of this newsgroup.
You might have a look at the directory iterator at
<http://www.boost.org/> which also provides a possibility to determine
the file size providing a portable interface.

TRIBBLE: david@tribble.com (private correspondence, 9 May 2000)

It appears that the original question ed@ftt.vsu.ru asked was about getting
the file size under HP-UX.  The answer, of course, is to call stat() or
fstat(), which is a POSIX call that works under all flavors of Unix,
including HP-UX.  Even MS/Win32 has workable stat() and fstat() functions
(declared <sys/stat.h>).

No such functions exist under ISO C or C++, however, even though it has
been suggested many times in the past.  The problem is that mandating
such a function for the standard library is simple task for Unix-like
systems (where files are simply streams of bytes), but extremely difficult
on systems that have to deal with blocking sizes and the like (such as
IBM MVS systems).

If you want your code to be *mostly* portable, knowing that it won't be
expected to run on non-POSIX-like systems, you can safely and "portably"
use stat().  Your code won't be "universally portable", but it will be
"mostly portable".

RODRIGUEZ: CRODRIGU@mobius.com (private correspondence, 11 May 2000)

what's not portable about the following?

ifstream in;
in.open(fileNane, ios::binary);
in.seekg(0, ios::end); // move to the end
unsigned long int fileSize = in.tellg();
ifs.seekg(0, ios::beg); // go back to the beginning

KUEHL: dietmar_kuehl@yahoo.com (private correspondence, 11 May 2000)

No, this is not portable at all: There is no requirement that a stream
position can be converted to an integral type. You have to convert it
to a stream offset first, eg.

  unsigned long int fileSize = std::streamoff(in.tellg());

For binary files and the "C" locale this should be OK. For text files
or if you are using a different than the "C" locale, things might be
different. Also, I'm always feeling uncomfortable with this approach.
Probably, I would just use my directory iterator stuff to determine
the file system size of a file.... (see <http://www.boost.org/>; I'm
working on an update which will allow file attribute access give
basically a file name, too).

______________________________________________
cpptips mailing list
http://cpptips.hyperformix.com