【问题标题】:Getting number of files in StorageFolder获取 StorageFolder 中的文件数
【发布时间】:2016-08-15 14:37:06
【问题描述】:

我正在使用 Windows Phone 8.1(RT) 应用程序,我想知道如何获取 StorageFolder 中的文件数

我知道我们可以使用StorageFolder.GetFilesAsync() 然后检查返回的列表的计数。 但是由于这个方法耗时太长并且返回所有项目,有没有更有效的方法来完成这项工作?

【问题讨论】:

  • 您只是想从自己的隔离存储目录中获取文件,还是尝试从其他地方(例如图片库或音乐库)获取文件?
  • @PeterTorr-MSFT:来自应用程序的本地存储(隔离),但如果可能的话,想知道两者。
  • 没有直接的方法来获取计数。但是由于这些文件由应用程序保存,您可以在 localsettings 中跟踪添加/删除的文件并用于快速访问,您可以从 localSettings 获取文件数量。 PS本地存储甚至不提供文件存在:(必须在try catch中访问文件以检查文件是否存在
  • @MuhammadSaifullah :目前不知何故使用 localsettings 方法,我对这种方法并不满意。感谢您的建议。希望微软通过 win10 提升游戏水平。

标签: c# windows-runtime windows-phone-8.1


【解决方案1】:

如果您使用 Win32 API 来获取文件计数,您可以获得快 3 个数量级的性能,但它仅适用于您的本地存储目录(它不适用于图片或音乐等代理位置)。例如,给定以下 C++/CX 组件:

标题

public ref struct FilePerfTest sealed
{
  Windows::Foundation::IAsyncOperation<uint32>^ GetFileCountWin32Async();
  uint32 GetFileCountWin32();
};

实施

uint32 FilePerfTest::GetFileCountWin32()
{
  std::wstring localFolderPath(ApplicationData::Current->LocalFolder->Path->Data());
  localFolderPath += L"\\Test\\*";
  uint32 found = 0;
  WIN32_FIND_DATA findData{0};
  HANDLE hFile = FindFirstFileEx(localFolderPath.c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH);

  if (hFile == INVALID_HANDLE_VALUE)
    throw ref new Platform::Exception(GetLastError(), L"Can't FindFirstFile");
  do
  {
    if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
      ++found;
  } while (FindNextFile(hFile, &findData) != 0);

  auto hr = GetLastError();
  FindClose(hFile);
  if (hr != ERROR_NO_MORE_FILES)
    throw ref new Platform::Exception(hr, L"Error finding files");

  return found;
}

Windows::Foundation::IAsyncOperation<uint32>^ FilePerfTest::GetFileCountWin32Async()
{
  return concurrency::create_async([this]
  {
    return GetFileCountWin32();
  });
}

如果我在 Lumia 920 上以 Release 模式测试以获取 1,000 个文件,Win32 版本所需的时间不到 5 毫秒(如果您使用非异步模式则更快)版本,在那个速度下真的不需要异步),而使用 StorageFolder.GetFilesAsync().Count 需要超过 6

编辑 7/1/15

请注意,如果您的目标是 Windows 桌面应用程序,您可以使用 StorageFolder.CreateFileQuery 方法创建批量查询,这样应该会更快。但不幸的是,Phone 8.1 不支持它

【讨论】:

  • 这很好,但我想知道是否还有其他方法可以查询文件系统中的其他位置?它甚至不适用于 c:\myfolder,我需要查询一个包含 35k 个文件的文件夹:(
  • 不幸的是没有支持的方式。如果这只是为了您自己的乐趣(而不是放在商店中的东西),您可以尝试对文件夹进行 ACL 以授予对 ALL APPLICATION PACAKGES 的读取访问权限...但使用风险自负,它可能不受支持等。
  • 感谢您的回复!不幸的是,我想最终在商店中发布。我最终做的是批量增量读取文件,但这并不理想。这会在 Windows 10 中修复吗?
  • 帖子被标记为电话,但您的示例文件夹听起来像 PC。无论哪种方式,正如我在编辑中指出的那样,使用文件查询有更好的机制,但首先没有好的方法来获取文件夹;您必须让用户使用FolderPicker 来选择它。这也应该适用于 Windows 10 中的电话
  • 谢谢彼得。我的应用确实是针对个人电脑的。我确实尝试过查询,但 GetItemCountAsync 给了我子文件夹的数量而不是文件。不过感谢您的编辑!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多