The Straight Dope

Go Back   Straight Dope Message Board > Main > General Questions

Reply
 
Thread Tools Display Modes
  #1  
Old 12-05-2003, 06:12 PM
Civil Defense Civil Defense is offline
BANNED
 
Join Date: Jan 2001
Location: Richmond, VA
Posts: 573
Retrieving the size of a file using C++

I've googled and googled and I can't seem to find any help

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!
Reply With Quote
Advertisements  
  #2  
Old 12-05-2003, 06:20 PM
Capt. Ridley's Shooting Party Capt. Ridley's Shooting Party is offline
Guest
 
Join Date: Jul 2003
_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.
Reply With Quote
  #3  
Old 12-05-2003, 06:24 PM
sengle sengle is offline
Guest
 
Join Date: Aug 2001
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.
Reply With Quote
  #4  
Old 12-05-2003, 08:51 PM
Punoqllads Punoqllads is offline
Charter Member
 
Join Date: Jul 2000
Location: Silly Cone Valley, CA
Posts: 3,010
There is a way to do it that is portable across all systems. In C++:

Code:
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:
Code:
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?
__________________
Loading, please wait...
Reply With Quote
  #5  
Old 12-05-2003, 09:25 PM
Una Persson Una Persson is offline
Straight Dope Science Advisory Board
 
Join Date: Mar 2000
Location: On the dance floor.
Posts: 14,263
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.
Reply With Quote
  #6  
Old 12-05-2003, 11:19 PM
LordVor LordVor is offline
Guest
 
Join Date: Jan 2001
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
Reply With Quote
  #7  
Old 12-05-2003, 11:58 PM
Cerowyn Cerowyn is offline
Guest
 
Join Date: Oct 2000
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.
Reply With Quote
  #8  
Old 12-06-2003, 12:26 AM
Mr2001 Mr2001 is offline
Guest
 
Join Date: Dec 1999
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:
Code:
__int64 GetFileSize(System::String * filename)
{
    System::IO::FileInfo * fi = new System::IO::FileInfo(filename);
    return fi->Length;
}
Reply With Quote
  #9  
Old 12-09-2003, 02:51 PM
Punoqllads Punoqllads is offline
Charter Member
 
Join Date: Jul 2000
Location: Silly Cone Valley, CA
Posts: 3,010
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).
__________________
Loading, please wait...
Reply With Quote
  #10  
Old 12-09-2003, 03:53 PM
XPav XPav is offline
Guest
 
Join Date: Jun 2002
fstat is a UNIX system call. It's not available to Windows.

Standard C++ would look like so:

Code:
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

Code:
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.
Reply With Quote
  #11  
Old 12-09-2003, 04:11 PM
Civil Defense Civil Defense is offline
BANNED
 
Join Date: Jan 2001
Location: Richmond, VA
Posts: 573
Thanks, guys. The solution I finally used was:

System::IO::FileInfo *fInfo = new FileInfo(dlgOpen->FileName);
txtSize->Text = fInfo->Length.ToString();
Reply With Quote
  #12  
Old 12-09-2003, 04:12 PM
spinky spinky is offline
Guest
 
Join Date: Nov 2002
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.
Reply With Quote
  #13  
Old 12-09-2003, 05:09 PM
np_complete np_complete is offline
Guest
 
Join Date: Aug 2003
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:

Code:
#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

SPOILER:
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.
Reply With Quote
  #14  
Old 12-09-2003, 05:13 PM
Cerowyn Cerowyn is offline
Guest
 
Join Date: Oct 2000
Quote:
Originally posted by XPav
fstat is a UNIX system call. It's not available to Windows.
Not only is it available with Microsoft C/C++, but they provide a 64-bit version as well.
Reply With Quote
  #15  
Old 12-09-2003, 05:22 PM
Punoqllads Punoqllads is offline
Charter Member
 
Join Date: Jul 2000
Location: Silly Cone Valley, CA
Posts: 3,010
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.
Reply With Quote
  #16  
Old 12-09-2003, 05:37 PM
np_complete np_complete is offline
Guest
 
Join Date: Aug 2003
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.
Reply With Quote
  #17  
Old 12-10-2003, 02:22 AM
Mr2001 Mr2001 is offline
Guest
 
Join Date: Dec 1999
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.
Reply With Quote
  #18  
Old 12-10-2003, 06:41 PM
XPav XPav is offline
Guest
 
Join Date: Jun 2002
Quote:
Originally posted by Cerowyn
Not only is it available with Microsoft C/C++, but they provide a 64-bit version as well.
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.
Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 12:25 AM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

Send questions for Cecil Adams to: cecil@chicagoreader.com

Send comments about this website to: webmaster@straightdope.com

Terms of Use / Privacy Policy

Advertise on the Straight Dope!
(Your direct line to thousands of the smartest, hippest people on the planet, plus a few total dipsticks.)

Publishers - interested in subscribing to the Straight Dope?
Write to: sdsubscriptions@chicagoreader.com.

Copyright © 2013 Sun-Times Media, LLC.