Размер файла на диске используя iostream

Добрый вечер, комрады
Пытаюсь вот тут настоящую магию постичь, но вот бубен дома забыл и духи меня покинули.

Ситуация: есть файл на диске (NTFS) размером в 22 гигабайта или 23,056,544,700 байтов, если верить проводнику по дебрям Windows 7 X64 с 8ГБ оперативной памяти (хотя какая раззница?)

А вот мой маленький кусочек кода показывает, что размер файла всего 1.5 гигабайта или 1.581.708.220 байт, что немного не соответствует инстине.

Вот она, моя прелесть
#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;
}


Как видно, размер я пытаюсь писать в __int64, так что нулей там точно должно хватить.
Собственно вопрос: А что такое?

Спасибо! :)

P.S.: С маленькими файлами все прекрасно работает — проверял.
  • Вопрос задан
  • 4794 просмотра
Решения вопроса 1
Здравствуйте!

Тут весь в вопрос не в __int64 в вашем коде, а в реализации ifstream — она зависит от платформы и, вообще говоря, реализация в Windows работает не очень хорошо для определения размера больших файлов.
Продолжая идти по пути с ifstream можно попробовать suppression.tellg().seekpos().
А вообще я бы рекомендовал другие способы для определения размера файла, например:
— функции _stat64/_fstat64
— boost::filesystem::file_size
— функцию WinAPI GetFileSize()
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Я так понимаю, что _stat64/_fstat64 не зависят от платформы?

Да, должны давать одинаково корректные результаты в 32-разрядных и 64-разрядных ОС (чего нельзя сказать об ifstream).
Ответ написан
Комментировать
Старые реализации Майрософтовского STL (msvc 9.0 и младше) не поддерживали файлы большого объема. Чтобы посмотреть максимальный размер файла, с которым вы можете работать, выведите максимальную позицию смещения в потоке:
std::numeric_limits<std::streamoff>::max()

Получите те самые (2^32) / 2.

В msvc 10.0 это поправили, и Вы увидите (2 ^ 64) / 2.
На GCC также все будет отлично.
Ответ написан
Комментировать
@Door
Может быть ещё нужно:
#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;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы