У меня есть функция, чтобы получить 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;
}
По крайней мере, для 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, его запись в таблице основного файла).
Ваше решение уже достаточно быстро, чтобы запросить размер файла.
В Windows, по крайней мере для NTFS и FAT, драйвер файловой системы будет сохранять размер файла в кеше, поэтому он довольно быстро запрашивает его. Самая трудоемкая работа — это переключение с режима пользователя на режим ядра, а не на обработку драйвера файловой системы.
Если вы хотите сделать это еще быстрее, вы должны использовать собственную политику кэширования в пользовательском режиме, например, специальная хеш-таблица, чтобы избежать переключения из режима пользователя в режим ядра. Но я не рекомендую вам делать это, потому что вы получите небольшую производительность.
PS: Вам лучше избегать высказываний Unicode::AnsiToUnicode(widePath, filepath);
в вашем теле функции. Эта функция довольно трудоемкая.
Просто идея (я ее не проверял), но я ожидал
GetFileAttributesEx
Быть самым быстрым на системном уровне. Это
избегает необходимости открывать файл, и логично, я бы ожидал
быть быстрее чем FindFirstFile
, так как это не должно
сохранить любую информацию для продолжения поиска.
Вы могли бы сделать свой собственный, но я не понимаю, почему ваш подход медленный:
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;
}