Я пытаюсь получить размер файла большого файла (12gb +), и я не хочу открывать файл, чтобы сделать это, поскольку я предполагаю, что это будет много ресурсов. Есть ли хороший API для этого? Я в среде Windows.
Проверить размер файла, не открывая файл в C++?
Ответ 1
Вам следует позвонить GetFileSizeEx
, который проще в использовании, чем предыдущий GetFileSize
. Вам нужно будет открыть файл, вызвав CreateFile
, но это дешевая операция. Ваше предположение, что открытие файла дорого, даже 12-гигабайтный файл, является ложным.
Чтобы выполнить задание, вы можете использовать следующую функцию:
__int64 FileSize(const wchar_t* name)
{
HANDLE hFile = CreateFile(name, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile==INVALID_HANDLE_VALUE)
return -1; // error condition, could call GetLastError to find out more
LARGE_INTEGER size;
if (!GetFileSizeEx(hFile, &size))
{
CloseHandle(hFile);
return -1; // error condition, could call GetLastError to find out more
}
CloseHandle(hFile);
return size.QuadPart;
}
Существуют другие вызовы API, которые возвратят вам размер файла, не заставляя вас создавать дескриптор файла, в частности GetFileAttributesEx
. Однако совершенно правдоподобно, что эта функция просто откроет файл за кулисами.
__int64 FileSize(const wchar_t* name)
{
WIN32_FILE_ATTRIBUTE_DATA fad;
if (!GetFileAttributesEx(name, GetFileExInfoStandard, &fad))
return -1; // error condition, could call GetLastError to find out more
LARGE_INTEGER size;
size.HighPart = fad.nFileSizeHigh;
size.LowPart = fad.nFileSizeLow;
return size.QuadPart;
}
Если вы компилируете Visual Studio и хотите избежать вызова API Win32, вы можете использовать _wstat64
.
Ниже приведена версия функции _wstat64
:
__int64 FileSize(const wchar_t* name)
{
__stat64 buf;
if (_wstat64(name, &buf) != 0)
return -1; // error, could use errno to find out more
return buf.st_size;
}
Если производительность когда-либо становилась проблемой для вас, то вы должны разделить различные варианты на всех платформах, на которые вы нацелились, чтобы принять решение. Не предполагайте, что API, которые не требуют вызова CreateFile
, будут быстрее. Они могут быть, но вы не узнаете, пока не придумаете.
Ответ 2
Я также жил со страхом цены, заплаченной за открытие файла, и закрыл его, чтобы получить его размер. И решил спросить счетчик производительности ^ и посмотрите, насколько дорогими являются операции.
Это количество циклов, необходимых для выполнения 1 запроса размера файла в том же файле тремя способами. Протестировано на 2 файла: 150 МБ и 1,5 ГБ. Получите +/- 10% -ные колебания, поэтому они, похоже, не зависят от фактического размера файла. (очевидно, это зависит от процессора, но это дает вам хорошую точку зрения)
- 190 циклов -
CreateFile
,GetFileSizeEx
,CloseHandle
- 40 циклов -
GetFileAttributesEx
- 150 циклов -
FindFirstFile
,FindClose
GIST с используемым кодом ^ доступен здесь.
Как мы можем видеть из этого теста очень научный:), самый медленный на самом деле является файловым открывателем. 2-й самый медленный - это поиск файлов, а победитель - читатель атрибутов. Теперь, с точки зрения надежности, CreateFile
должен быть предпочтительнее других 2. Но мне все еще не нравится концепция открытия файла, чтобы просто прочитать его размер... Если я не делая размер критичных вещей, я пойду за атрибутами.
PS: Когда у меня будет время, я попытаюсь прочитать размеры файлов, которые открываются и пишу. Но не сейчас...
Ответ 3
Еще одна опция, использующая функцию FindFirstFile
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
LPCTSTR lpFileName = L"C:\\Foo\\Bar.ext";
hFind = FindFirstFile(lpFileName , &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
printf ("File not found (%d)\n", GetLastError());
return -1;
}
else
{
ULONGLONG FileSize = FindFileData.nFileSizeHigh;
FileSize <<= sizeof( FindFileData.nFileSizeHigh ) * 8;
FileSize |= FindFileData.nFileSizeLow;
_tprintf (TEXT("file size is %u\n"), FileSize);
FindClose(hFind);
}
return 0;
}
Ответ 4
В С++ 17 есть file_size как часть стандартной библиотеки. (Тогда разработчик должен решить, как это сделать эффективно!)
Ответ 5
Как насчет Функция GetFileSize?