比StorageFolder.GetFilesAsync()更快的获取文件夹中文件的方法是什么?

7

StorageFolder.GetFilesAsync非常慢:

  • 对于包含约3500个文件的文件夹,需要大约7秒钟。

在Windows Phone 8.0 Silverlight中,我能够更快地获取CameraRoll的内容(通过MediaLibrary):

  • 对于同样数量的文件,只需小于1秒钟。

是否有可能加速GetFilesAsync,或者有没有其他获取文件夹中文件的替代方法?

我需要立即提取照片文件的信息,例如GeotagDateTaken。您可以在我的应用GeoPhoto中看到它们在Silverlight中加载得多么快。我现在正在尝试将其移植到UWP。我已经实现了缓存(通过将geotag和DateTaken与图片路径进行映射),因此我仅需要以后的应用程序启动时的图片路径。尚未缓存的相片可以稍后显示(在长时间的GetFilesAsync调用之后),但是重要的是,在启动应用程序后立即为用户提供他可以与之交互的内容。


1
你尝试过使用 Windows.Storage.BulkAccess 命名空间吗?FileInformationFactory.GetFilesAsyncFileInformationFactory.GetVirtualizedFilesVector 可能更快。 - Raymond Chen
@RaymondChen - 我刚刚尝试了FileInformationFactory.GetFilesAsync方法,想看看它是否比我以前从未使用过的方法更快...在我编写的一个简单示例中,有10500个文件,返回需要45-60秒,与StorageFolder.GetFilesAsync时间相似。 - WiredPrairie
你的文件夹是否在索引位置(如库)中?如果不是,那么只能访问磁盘。此外,你尝试过 GetVirtualizedFilesVector 吗?我猜想虚拟向量在前期工作上要少一些,因为它可以懒惰地生成内容。 - Raymond Chen
@tipa 你能添加一下你使用的要求吗?你需要将目录中的所有文件显示在列表中吗?还是需要在代码后台中使用它们并搜索文件。这些细节可能有助于找到解决方案。 - Herdo
@Herdo,我已经添加了我的用例要求。希望这有助于找到解决方案。 - tipa
@tipa 你是否考虑分块处理/获取文件?或者你需要一开始就全部获取? - Herdo
2个回答

1

编辑: 由于我的原始回答似乎没有帮助到你,我希望这个回答可以解决你的问题。

我创建了一个包含约4000个文件的文件夹,仅供测试,并使用了一个计时器来记录时间。
只是读取文件夹中的每个项目花费的时间为:

System.IO.Directory.GetFiles(): 0.2秒

Windows.Storage.StorageFolder.GetFilesAsync 约5.5秒

多次执行并以不同顺序执行

我知道这只是将文件名作为字符串返回,但根据您用于读取图片的库的不同,这可能仍然有所帮助。

原始回答:
当您获得路径作为字符串(例如从ApplicationData.Current.LocalFolder.Path)时,您可以使用System.IO.Directory.GetFiles(string path)。它不会返回特定的对象,而是返回路径作为字符串。您可以将其与静态类System.IO.File一起使用。

它还允许您传递searchPattern,使您可以使用像*和?这样的占位符,并且它是同步工作的,但通过此方法检索文件非常快速。

这个问题不仅古老而且对速度问题的缺乏非常清楚。你的回答如何解决这个问题? - H H

1
我想知道您是否阅读了这篇文章:https://www.suchan.cz/2014/07/file-io-best-practices-in-windows-and-phone-apps-part-1-available-apis-and-file-exists-checking/。该文章与编程有关,涉及最佳实践和可用的API以及文件存在性检查。请注意,内容应保留HTML标签,但需要使其更加通俗易懂。

Windows 8.1 - 最快的方法是使用新的StorageFolder.TryGetItemAsync方法,但与其他方法相比只有微弱优势。这里的主要好处绝对是所需的简单代码,如果文件不存在,则不需要任何异常捕获。如果不需要原始同步上下文,则同步方法的结果类似于Windows 8平台,同步方法是更好的选择。

简而言之,在检查目标文件是否存在方面,在WP8和WP8.1 Silverlight上最快的方法是File.Exists,在Windows 8和WP8.1 XAML上,应使用StorageFolder.GetFileAsync,在Windows 8.1上使用新方法StorageFolder.TryGetItemAsync。在任何平台上都不要使用从StorageFolder.GetFilesAsync返回的StorageFiles的迭代,它非常慢。此外,如果您不需要继续在原始线程上运行,可以在WP8.1 XAML、Windows 8和Windows 8.1平台上使用同步替代方法。

或者类似这样的内容?

StorageFolder.GetItemsAsync(UInt32, UInt32) 

获取前X个文件以立即向用户提供所需的反馈。之后再加载其余文件。

https://msdn.microsoft.com/en-us/library/windows/apps/br227287.aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接