10

I need to determin the byte size of a file.

The coding language is C++ and the code should work with Linux, windows and any other operating system. This implies using standard C or C++ functions/classes.

This trivial need has apparently no trivial solution.

1

8 Answers 8

12

Using std's stream you can use:

std::ifstream ifile(....); ifile.seekg(0, std::ios_base::end);//seek to end //now get current position as length of file ifile.tellg(); 

If you deal with write only file (std::ofstream), then methods are some another:

ofile.seekp(0, std::ios_base::end); ofile.tellp(); 
Sign up to request clarification or add additional context in comments.

9 Comments

Open the file in binary or you might get the wrong result. Text ifstreams could do \r\n to \n translation for instance.
The problem is that tellg() returns a value of type streampos. It is usually an int, but it can also be another type. Though I'll keep it as an answer.
Isn't an ifstream inefficient if you just want to get the file size? stat() will do it without having to open & seek.
-1: Opening file is bad idea. Moreover, you cannot check size of, for example, /etc/shadow this way.
File could be failed to open. -1
|
6

You can use stat system call:

#ifdef WIN32 _stat64() #else stat64() 

1 Comment

It's worth noting that stat family of functions is part of POSIX, so they work on UNIX and UNIX-like systems as well.
2

If you only need the file size this is certainly overkill but in general I would go with Boost.Filesystem for platform-independent file operations. Amongst other attribute functions it contains

template <class Path> uintmax_t file_size(const Path& p); 

You can find the reference here. Although Boost Libraries may seem huge I found it to often implement things very efficiently. You could also only extract the function you need but this might proof difficult as Boost is rather complex.

2 Comments

Why boost when there are already numerous ways to easily do this without boost?
Chances are that if you work with files you might need more file functionality: boost is a good choice for that - standard body agrees and will add boost based library to STL. If you really only need file size - by all means use @Dewfy answer
1

Simples:

std::ifstream ifs; ifs.open("mybigfile.txt", std::ios::bin); ifs.seekg(0, std::ios::end); std::fpos pos = ifs.tellg(); 

2 Comments

On 32-bit systems, size_t is 32 bits. So this fails with files of 4GB or larger.
I wrote this off the cuff with no reference. Looking at my code there are some problems which I have corrected.
1
std::intmax_t file_size(std::string_view const& fn) { std::filebuf fb; return fb.open(fn.data(), std::ios::binary | std::ios::in) ? std::intmax_t(fb.pubseekoff({}, std::ios::end, std::ios::in)) : std::intmax_t(-1); } 

We sacrifice 1 bit for the error indicator and standard disclaimers apply when running on 32-bit systems. Use std::filesystem::file_size(), if possible, as std::filebuf may dynamically allocate buffers for file io. This would make all the iostream-based methods wasteful and slow. Files were/are meant to be streamed, though much more so in the past than today, which relegates file sizes to secondary importance.

Working example.

Comments

0

Portability requires you to use the least common denominators, which would be C. (not c++) The method that I use is the following.

#include <stdio.h> long filesize(const char *filename) { FILE *f = fopen(filename,"rb"); /* open the file in read only */ long size = 0; if (fseek(f,0,SEEK_END)==0) /* seek was successful */ size = ftell(f); fclose(f); return size; } 

2 Comments

Too bad if you have a file >2GB in size on platforms with 32 bit long int
@DavidHeffernan there are 64 bit versions of those functions. but that aside, this requires you to be able to open the file and is also a lot slower.
0

The prize for absolute inefficiency would go to:

auto file_size(std::string_view const& fn) { std::ifstream ifs(fn.data(), std::ios::binary); return std::distance(std::istream_iterator<char>(ifs), {}); } 

Example.

Comments

-1

Often we want to get things done in the most portable manner, but in certain situations, especially like this, I would strongly recommend using system API's for best performance.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.