Windows cpp file size

How to get File Size in C++?

See my new website at cppstories.com

Before C++17 we could often complain that even simple tasks as getting a file size were complicated. With std::filesystem things get a bit easier!

Get a File Size

STL before C++17 didn’t contain any direct facilities to work with a filesystem. We could only use third party libraries (like Boost), or system APIs.

To get file size, a popular technique was to open a file and then use file position pointer to compute the size.

Here’s some code that uses stream library:

Another option was also to open a file in append mode (`std::ios::ate`) and then there was no need to move the file pointer — as it was automatically positioned at the end. On Windows you can also use GetFileSizeEx or FindFirstFileEx (as mentioned in a comment by Artem R.):

I haven’t explored all of the possible options, so let ma know what is your way of getting file size.

How about C++17? Is there any chance to have a simpler code and maybe portable?

The Series

This article is part of my series about C++17 Library Utilities. Here’s the list of the topics in the series:

Resources about C++17 STL:

File Size with std::filesystem

C++17 brings std::filesystem which streamlines a lot of tasks on files and directories. Not only you can quickly get file size, its attributes, but also create new directories, iterate through files, work with path objects.

The new library gives us two functions that we can use:

  • std::uintmax_t std::filesystem::file_size( const std::filesystem::path& p );
  • std::uintmax_t std::filesystem::directory_entry::file_size() const;

The first function is a free function in std::filesystem , the second one is a method in directory_entry .

Each method also has an overload, as it can throw an exception or return an error code (through an output parameter).

For example, we can get a file size with the following code:

Or the version with error_codes:

You may ask why do we have two methods — as a free function and as a method.

The reason is that directory_entry caches file attributes. That’s why if you iterate over a directory, or you access file several times, then caching might bring performance improvements.

If the file or the directory pointed by directory_entry changes then you need to call the directory_entry::refresh() method to update the cache, otherwise you might get «old» values for your queries.

Читайте также:  Linux как расширить диск gparted

You can play with the code in this interactive sample:

(Here’s also a code at Coliru).

Summary

In this short post, you’ve seen how to use file_size function from std::filesystem . I encourage you to explore this new and powerful addition to C++17. If you work with files and directories, this might make your code much more comfortable and portable.

See the next article in the series where I discuss File permissions and performance of file_size : std:filesystem::file_size Advantages and Differences

If you want to get additional C++ resources, exlusive articles, early access content, private Discord server and weekly curated news, check out my Patreon website: (see all benefits):

GetFileSize function (fileapi.h)

Retrieves the size of the specified file, in bytes.

It is recommended that you use GetFileSizeEx.

Syntax

Parameters

A handle to the file.

A pointer to the variable where the high-order doubleword of the file size is returned. This parameter can be NULL if the application does not require the high-order doubleword.

Return value

If the function succeeds, the return value is the low-order doubleword of the file size, and, if lpFileSizeHigh is non-NULL, the function puts the high-order doubleword of the file size into the variable pointed to by that parameter.

If the function fails and lpFileSizeHigh is NULL, the return value is INVALID_FILE_SIZE. To get extended error information, call GetLastError. When lpFileSizeHigh is NULL, the results returned for large files are ambiguous, and you will not be able to determine the actual size of the file. It is recommended that you use GetFileSizeEx instead.

If the function fails and lpFileSizeHigh is non-NULL, the return value is INVALID_FILE_SIZE and GetLastError will return a value other than NO_ERROR.

Remarks

You cannot use the GetFileSize function with a handle of a nonseeking device such as a pipe or a communications device. To determine the file type for hFile, use the GetFileType function.

The GetFileSize function retrieves the uncompressed size of a file. Use the GetCompressedFileSize function to obtain the compressed size of a file.

Note that if the return value is INVALID_FILE_SIZE (0xffffffff), an application must call GetLastError to determine whether the function has succeeded or failed. The reason the function may appear to fail when it has not is that lpFileSizeHigh could be non-NULL or the file size could be 0xffffffff. In this case, GetLastError will return NO_ERROR (0) upon success. Because of this behavior, it is recommended that you use GetFileSizeEx instead.

Transacted Operations:В В If there is a transaction bound to the file handle, then the function returns information for the isolated file view.

Читайте также:  Linux path to chrome

In WindowsВ 8 and Windows ServerВ 2012, this function is supported by the following technologies.

Check the file-size without opening file in C++?

I’m trying to get the filesize of a large file (12gb+) and I don’t want to open the file to do so as I assume this would eat a lot of resources. Is there any good API to do so with? I’m in a Windows environment.

5 Answers 5

You should call GetFileSizeEx which is easier to use than the older GetFileSize . You will need to open the file by calling CreateFile but that’s a cheap operation. Your assumption that opening a file is expensive, even a 12GB file, is false.

You could use the following function to get the job done:

There are other API calls that will return you the file size without forcing you to create a file handle, notably GetFileAttributesEx . However, it’s perfectly plausible that this function will just open the file behind the scenes.

If you are compiling with Visual Studio and want to avoid calling Win32 APIs then you can use _wstat64 .

Here is a _wstat64 based version of the function:

If performance ever became an issue for you then you should time the various options on all the platforms that you target in order to reach a decision. Don’t assume that the APIs that don’t require you to call CreateFile will be faster. They might be but you won’t know until you have timed it.

I’ve also lived with the fear of the price paid for opening a file and closing it just to get its size. And decided to ask the performance counter^ and see how expensive the operations really are.

This is the number of cycles it took to execute 1 file size query on the same file with the three methods. Tested on 2 files: 150 MB and 1.5 GB. Got +/- 10% fluctuations so they don’t seem to be affected by actual file size. (obviously this depend on CPU but it gives you a good vantage point)

  • 190 cycles — CreateFile , GetFileSizeEx , CloseHandle
  • 40 cycles — GetFileAttributesEx
  • 150 cycles — FindFirstFile , FindClose

As we can see from this highly scientific 🙂 test, slowest is actually the file opener. 2nd slowest is the file finder while the winner is the attributes reader. Now, in terms of reliability, CreateFile should be preferred over the other 2. But I still don’t like the concept of opening a file just to read its size. Unless I’m doing size critical stuff, I’ll go for the Attributes.

PS: When I’ll have time I’ll try to read sizes of files that are opened and am writing to. But not right now.

How to get the file size in bytes with C++17

Are there pitfalls for specific operating systems, I should know of?

Читайте также:  Nvr регистратор под windows

There are many duplicates (1, 2, 3, 4, 5) of this question but they were answered decades ago. The very high voted answers in many of these questions are wrong today.

Methods from other (old QA’s) on .sx

tellg(), returns per definition a position but not necessarily bytes. The return type is not int .

2 Answers 2

As noted in comments, if you’re planning to use this function to decide how many bytes to read from the file, keep in mind that.

. unless the file is exclusively opened by you, its size can be changed between the time you ask for it and the time you try to read data from it.
– Nicol Bolas

C++17 brings std::filesystem which streamlines a lot of tasks on files and directories. Not only you can quickly get file size, its attributes, but also create new directories, iterate through files, work with path objects.

The new library gives us two functions that we can use:

The first function is a free function in std::filesystem , the second one is a method in directory_entry .

Each method also has an overload, as it can throw an exception or return an error code (through an output parameter). Below is the detail code explaining all the possible cases.

std::experimental::filesystem:: file_size

Language
Standard Library Headers
Freestanding and hosted implementations
Named requirements
Language support library
Concepts library (C++20)
Diagnostics library
Utilities library
Strings library
Containers library
Iterators library
Ranges library (C++20)
Algorithms library
Numerics library
Localizations library
Input/output library
Filesystem library (C++17)
Regular expressions library (C++11)
Atomic operations library (C++11)
Thread support library (C++11)
Technical Specifications
Filesystem library (filesystem TS)
Library fundamentals (library fundamentals TS)
Library fundamentals 2 (library fundamentals TS v2)
Library fundamentals 3 (library fundamentals TS v3)
Extensions for parallelism (parallelism TS)
Extensions for parallelism 2 (parallelism TS v2)
Extensions for concurrency (concurrency TS)
Concepts (concepts TS)
Ranges (ranges TS)
Reflection (reflection TS)
Mathematical special functions (special functions TR)

Returns the size of the regular file p , determined as if by reading the st_size member of the structure obtained by POSIX stat (symlinks are followed)

Attempting to determine the size of a directory (as well as any other file that is not a regular file or a symlink) is treated as an error.

The non-throwing overload returns returns — 1 on errors.

Оцените статью