M
M
max_mara2013-03-03 02:42:14
C++ / C#
max_mara, 2013-03-03 02:42:14

File size on disk using iostream

Good evening, comrades
I'm trying to comprehend real magic here, but I forgot the tambourine at home and the spirits left me.

Situation: there is a file on a disk (NTFS) with a size of 22 gigabytes, or 23,056,544,700 bytes, according to the Windows 7 X64 wilds explorer with 8GB of RAM (but what's the difference?)

But my little piece of code shows that the file size is only 1.5 gigabytes or 1.581.708.220 bytes, which is slightly out of line.

Here she is, my beauty

#include <iostream>
#include <fstream>

using namespace std;

/**
 * Suppression file
 */
char * suppressionFile = "D:\\path_to_very_big_file.csv";

ifstream          suppression;
unsigned __int64  suppressionLength;

/**
 * Entry point
 */
int main(void) {
  suppression.open(suppressionFile, ifstream::in);
  if (!suppression.is_open()) {
    cout << "Cannot open file" << endl;
    return 1;
  }

  if (!suppression.seekg(0, ifstream::end).good()) {
    cout << "Cannot move pointer to the end of the file" << endl;
    return 1;
  }
  suppressionLength = suppression.tellg();

  cout << suppressionLength << endl;
  cin >> suppressionLength;


  suppression.close();
  return 0;
}


As you can see, I'm trying to write the size in __int64, so there should definitely be enough zeros there.
Actually the question is: What is it?

Thank you! :)

PS: Everything works fine with small files - I checked it.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
V
Vitaly Shibaev, 2013-03-03
@max_mara

Hello!
The question here is not __int64 in your code, but the implementation of ifstream - it depends on the platform and, in general, the implementation on Windows does not work very well for determining the size of large files.
Continuing down the ifstream path, you can try suppression.tellg().seekpos().
In general, I would recommend other ways to determine the file size, for example:
- _stat64 / _fstat64 functions
- boost:: filesystem:: file_size
- WinAPI GetFileSize () function

V
Vitaly Shibaev, 2013-03-03
@shibaev

I take it that _stat64/_fstat64 are platform independent?

Yes, they should give equally correct results in 32-bit and 64-bit OS (which cannot be said about ifstream).

A
Alexander Yudaev, 2013-03-03
@oYASo

Old implementations of the Microsoft STL (msvc 9.0 and earlier) did not support large files. To see the maximum file size you can work with, print the maximum offset position in the stream:

std::numeric_limits<std::streamoff>::max()

Get those same (2^32) / 2.
In msvc 10.0 this has been fixed and you will see (2 ^ 64) / 2.
Everything will be fine on GCC as well.

D
Door, 2013-03-04
@Door

It may also be needed:

#include <Windows.h>

typedef unsigned long long int file_size_t;

// Return 0 if fail
inline file_size_t FileSize(LPCTSTR fileName)
{
  file_size_t size = 0;

  HANDLE file = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if(file != INVALID_HANDLE_VALUE)
  {
    LARGE_INTEGER fileSize = {};
    if(GetFileSizeEx(file, &fileSize))
    {
      size = ((static_cast<file_size_t>(
        fileSize.u.HighPart) << 32) | fileSize.u.LowPart);
    }
  }
  return size;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question