【问题标题】:Faster way to get File Size information C++获取文件大小信息的更快方法 C++
【发布时间】:2013-02-01 00:11:02
【问题描述】:

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

【问题讨论】:

  • 您可能想确认这是实际的慢代码位。我看不出有什么特别的原因,除非你的文件系统包含大量文件[因此,搜索所有文件需要一段时间才能打开它]。
  • @MatsPetersson 你说得有道理,当我发布这个时,我意识到它可能是 UnicodeToAnsi 函数,因为它涉及字符串操作。我重构了代码以减少这些代码的使用,并且已经将速度提高了 30%
  • 如果您正在执行“许多”AnsiToUnicode 调用,您可能需要构建一个缓存来检查您是否已经完成了此文件并返回前一个文件...一些散列可能会有所帮助。跨度>

标签: c++ optimization windows-ce


【解决方案1】:

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

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

【讨论】:

  • 从文件系统驱动的角度来看,目录也是文件。打开目录不能比打开常规文件快。
  • 这是一种享受,谢谢!结合这一点并减少对 AnsiToUnicode 的调用,我将以前索引所需的时间减半。每个更改都做出同等贡献。
  • @Jerry,你是对的。您的解决方案确实节省了打开时间。
  • 这也意味着您也不必在文件中查找。对我来说也是,因为我正在使用代码来计算许多文件的文件大小,所以我已经可以访问WIN32_FIND_DATAW,因此该操作也是“免费”的:D
【解决方案2】:

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

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      你可以自己动手,但我不明白为什么你的方法很慢:

      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;
      }
      

      【讨论】:

      • 我非常怀疑添加几层 C 库代码会使其更快。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      • 1970-01-01
      • 1970-01-01
      • 2021-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多