Оптимизация — более быстрый способ получить информацию о размере файла Переполнение стека

У меня есть функция, чтобы получить FileSize файла. Я запускаю это на WinCE. Вот мой текущий код, который кажется особенно медленным

int Directory::GetFileSize(const std::string &filepath)
{
int filesize = -1;

#ifdef linux
struct stat fileStats;
if(stat(filepath.c_str(), &fileStats) != -1)
filesize = fileStats.st_size;
#else
std::wstring widePath;
Unicode::AnsiToUnicode(widePath, filepath);

HANDLE hFile = CreateFile(widePath.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile > 0)
{
filesize = ::GetFileSize( hFile, NULL);
}

CloseHandle(hFile);
#endif

return filesize;
}

3

Решение

По крайней мере, для Windows, я думаю, я бы использовал что-то вроде этого:

__int64 Directory::GetFileSize(std::wstring const &path) {

WIN32_FIND_DATAW data;
HANDLE h = FindFirstFileW(path.c_str(), &data);
if (h == INVALID_HANDLE_VALUE)
return -1;

FindClose(h);

return data.nFileSizeLow | (__int64)data.nFileSizeHigh << 32;
}

Если используемый вами компилятор поддерживает его, вы можете использовать long long вместо __int64, Вы, вероятно, делаете не хочу использовать int тем не менее, поскольку это будет правильно работать только для файлов объемом до 2 гигабайт, а файлы, размер которых больше этого, теперь довольно распространены (хотя, возможно, не так часто встречаются на устройстве WinCE).

Я бы ожидать это будет быстрее, чем большинство других методов, хотя. Он вообще не требует открытия самого файла, просто находит запись в каталоге файла (или, в случае чего-то вроде NTFS, его запись в таблице основного файла).

11

Другие решения

Ваше решение уже достаточно быстро, чтобы запросить размер файла.

В Windows, по крайней мере для NTFS и FAT, драйвер файловой системы будет сохранять размер файла в кеше, поэтому он довольно быстро запрашивает его. Самая трудоемкая работа — это переключение с режима пользователя на режим ядра, а не на обработку драйвера файловой системы.

Если вы хотите сделать это еще быстрее, вы должны использовать собственную политику кэширования в пользовательском режиме, например, специальная хеш-таблица, чтобы избежать переключения из режима пользователя в режим ядра. Но я не рекомендую вам делать это, потому что вы получите небольшую производительность.

PS: Вам лучше избегать высказываний Unicode::AnsiToUnicode(widePath, filepath); в вашем теле функции. Эта функция довольно трудоемкая.

1

Просто идея (я ее не проверял), но я ожидал
GetFileAttributesEx Быть самым быстрым на системном уровне. Это
избегает необходимости открывать файл, и логично, я бы ожидал
быть быстрее чем FindFirstFile, так как это не должно
сохранить любую информацию для продолжения поиска.

1

Вы могли бы сделать свой собственный, но я не понимаю, почему ваш подход медленный:

int Get_Size( string path )
{
// #include <fstream>
FILE *pFile = NULL;

// get the file stream
fopen_s( &pFile, path.c_str(), "rb" );

// set the file pointer to end of file
fseek( pFile, 0, SEEK_END );

// get the file size
int Size = ftell( pFile );

// return the file pointer to begin of file if you want to read it
// rewind( pFile );

// close stream and release buffer
fclose( pFile );

return Size;
}
-1
По вопросам рекламы [email protected]