有什么正确的方法可以按路径获取文件吗

本文关键字:路径 获取 文件 什么 方法 | 更新日期: 2023-09-27 18:26:00

我在KnownFolders.VideosLibrary中有两个同名文件,在这种情况下,我无法通过其名称访问文件,因此它将只返回第一个。因此,除了解析文件夹中的所有文件之外,还有其他方法可以获得文件吗?

// this return two files 
var files = (await KnownFolders.VideosLibrary.GetFilesAsync()).Where(x => x.Name == "test.txt").ToArray();
// with this I can get only one file
StorageFile file = await KnownFolders.VideosLibrary.GetFileAsync("test.txt");
// of course I can parse it with query, but I would like to avoid it
// StorageFile myFile = (await KnownFolders.VideosLibrary.GetFilesAsync()).FirstOrDefault(x => x.FolderRelativeId == "something");

我知道FutureAccessList,但它最多只能容纳1000个文件,这对我来说是不够的。


请求后的一些澄清:

例如,让我们考虑使用SD卡在手机上运行该应用程序。我在视频中的手机内存中有一个名为test.txt的文件,同名文件也存在于Videos文件夹中的SD卡上。

在这种情况下,当您调用上面代码中的第一行时,您将获得两个文件,为了区分它们,系统提供了FolderRelativeId,因此具有相同名称的文件可以存在于一个"位置"中。如果你看一下每个文件夹的完整路径,可能会有C:'Viedos'test.txt和第二个D:'Videos'test.txt

现在,第一次运行时的用户使用FilePicker选择了一个文件,我已经记住了它的路径,例如D:'Videos'test.txt。在第二次运行该应用程序时,我希望使用其路径(或除受限FutureAccessList之外的其他方法)访问该文件。在过去,我经常用StorageFile.GetFileFromPathAsync(path);来做这件事,因为它似乎开始在W10中抛出UnauthorizedAccessException

有什么正确的方法可以按路径获取文件吗

您可以通过此获取IStorageFile的实例。

// If your have a StorageFile objece file then 
//fileUri = new Uri(file.Path);
string uri = fileUri.LocalPath;
int end = uri.LastIndexOf('''');
uri = uri.Substring(0, end + 1);
string name = Path.GetFileName(fileUri.LocalPath);
var folder = await StorageFolder.GetFolderFromPathAsync(uri);
IStorageFile file = await folder.GetFileAsync(name);
// Do something with file object

根据MS的此文档,应用程序可以选择退出允许文件存储在SD卡上。因此,媒体库可以拆分到设备的内部存储和SD卡

如果我做对了,你的解决方案是:

  • 选择退出上述功能
  • 您现在应该只在本地设备上搜索,而不是在SD卡上搜索
    • 这将在每个目录中产生唯一的文件名
  • 如果您的用例也需要在SD卡上搜索文件,您现在必须访问SD卡,并在此处查询文件

我不确定,单独访问SD卡的编码开销是否值得通过仅查询本地存储来获得性能提升。

当您在Windows 8.1应用程序中使用文件选择器打开文件时(我假设Windows 10的工作方式相同),您将获得该文件夹的权限令牌,该令牌将持续一段时间,或者直到您退出应用程序。重新打开应用程序时,必须重新获取文件夹的令牌。

阅读这篇关于StorageApplicationPermissions对象的文章。

我想,考虑到您没有访问应用程序中的根驱动器号的权限,因此不允许以这种方式导航文件夹结构,可以合理化调用StorageFile.GetFileFromPathAsync(path)时抛出的UnauthorizedAccessException。不过这只是猜测。

至于你的问题,你为什么不能这样做?

var file = (await KnownFolders.VideosLibrary.GetFilesAsync()).FirstOrDefault(x => x.Path == "D:'Videos'test.txt");

其中,D:'Videos'test.txt是从用户使用选择器选择的文件中获取的.Path属性值。

当VideosLibrary上有数百万个文件时,也许你可以预期它会慢一点。