3

我有一个函数来获取文件的 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;
}
4

4 回答 4

11

至少对于 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 GB 的文件,而大于 2 GB 的文件现在很常见(尽管在 WinCE 设备上可能不那么常见)。

不过,我希望这比大多数其他方法更快。它根本不需要打开文件本身,只需找到文件的目录条目(或者,在 NTFS 之类的情况下,它的主文件表条目)。

于 2013-01-31T15:27:40.363 回答
1

您的解决方案查询文件大小已经相当快了。

在 Windows 下,至少对于 NTFS 和 FAT,文件系统驱动程序会将文件大小保存在缓存中,因此查询起来相当快。涉及的最耗时的工作是从用户模式切换到内核模式,而不是文件系统驱动程序的处理。

如果你想让它更快,你必须在用户模式下使用你自己的缓存策略,例如一个特殊的哈希表,以避免从用户模式切换到内核模式。但我不建议您这样做,因为您将获得很少的性能。

PS:你最好避免Unicode::AnsiToUnicode(widePath, filepath);在你的函数体中声明。此功能相当耗时。

于 2013-01-31T14:59:32.953 回答
1

只是一个想法(我没有测试过),但我希望 GetFileAttributesEx在系统级别上最快。它避免了必须打开文件,从逻辑上讲,我希望它比 快FindFirstFile,因为它不需要维护任何信息来继续搜索。

于 2013-01-31T16:11:02.010 回答
-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;
}
于 2013-01-31T14:40:36.360 回答