我让我的用户从音乐库中选择文件。之后我在本地存储所选文件的路径。现在我的问题是如何从这些路径以编程方式访问文件?以下是我尝试过的几件事。
说我的路径名是 D:\ Xyz \ abc.mp3
StorageFolder S = KnownFolders.MusicLibrary;
备选方案1:
StorageFile MyFile = await S.GetFileAsync(“abc.mp3”); //找不到文件错误
//我认为这不起作用,因为GetFileAsync方法只能从当前文件夹中获取文件
备选方案2:
S =等待S.GetFolderAsync(“Xyz”); //之后我计划进行GetFileAsync。但这也会给文件夹找不到错误。
最后我尝试了 S = await S.GetFolderAsync(“D”);
关于我如何访问该文件或甚至是实现我的目标的替代方法的任何帮助都会非常棒!
P.S:StorageFile.GetFileFromPathAsync(“D:\ Xyz \ abc.mp3”)表示我无权访问。
答案 0 :(得分:10)
(回答重建更清楚)
如果您已在package.appxmanifest
档案中声明:
Music Library
功能
声明中的File Type Association
(如果您只访问音乐库,我不确定是否需要这样做)然后您就可以从Music Library
文件夹中检索文件,如下所示:
StorageFolder folder = KnownFolders.MusicLibrary;
// below code will work unless 'fileName.mp3' is in
// your Music folder either on phone or SD card
StorageFile file = await folder.GetFileAsync("fileName.mp3");
// you can access them also with path, but in this case
// also Folders must be in Music folder
string path = @"Test\ccc.mp3";
StorageFile file = await folder.GetFileAsync(path);
总结一下,你只能KnownFolders.MusicLibrary
对电话或SD卡上的文件,但在音乐文件夹中的文件 - 他们的路径将是:
C:\ Data \ Users \ Public \ Music \ test.mp3 - for Phone
D:\ Music \ Test \ test2.mp3 - 用于SD卡
请记住,StorageFolder.GetFileAsync()访问相对到StorageFolder(它也可以使用完整路径,请参阅下面的注释):
要检索的文件的名称(或相对于当前文件夹的路径)。
在这种情况下,要获取上述文件,您将使用以下文件名:test.mp3
和Test\test2.mp3
。
你不会能够获取其他文件,例如D:\xxx.mp3
- 它不在音乐库中 - 它在SD卡上,如果您想要访问它,您将拥有通过KnownFolders.RemovableDevices来完成 - 当您添加了所需的功能时,您应该能够通过完整路径访问它。但也please remember about the remark:
不要依赖此属性来访问文件,因为某些文件可能没有文件系统路径。例如,如果文件由URI支持,或者使用文件选择器选择,则不保证文件具有文件系统路径。
在我们的讨论中,确定您正在使用CommonFileQuery.OrderByName
来获取文件。正如我在那里检查的那样(IMO)可能是一个小错误 - 在VS描述中说:
深度查询的查询结果包括所查询文件夹的所有子文件夹中的所有文件,并根据指定的元数据对其进行排序。
运行一堆代码:
// a method to retrieve files from Musiic Library recursively
private async Task RetriveFilesInFolders(List<StorageFile> list, StorageFolder parent)
{
foreach (var item in await parent.GetFilesAsync()) list.Add(item);
foreach (var item in await parent.GetFoldersAsync()) await RetriveFilesInFolders(list, item);
}
// then I've used it like this:
StorageFolder folder = KnownFolders.MusicLibrary;
List<StorageFile> listOfFiles = new List<StorageFile>();
await RetriveFilesInFolders(listOfFiles, folder);
// as a result of above code I have a List of 5 files that are in Music Library
List<IStorageItem> filesFolders = (await folder.GetItemsAsync()).ToList();
List<StorageFile> items = (await folder.GetFilesAsync(CommonFileQuery.OrderByName)).ToList();
// as a result here I've 14 files that are in Music Library and SD card, and Phone
已经给出了结果:
你可以在调试模式下轻松查看Path
,你会发现第二种方法中的某些文件有D:\file.mp3
等等 - 它们不在音乐库中 - 所以你赢了'能够通过KnownFolders.MusicLibrary
获得它们。如果你想获得它们,那么你将不得不使用其他KnownFolders - 在这种情况下是SD卡:
StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;
StorageFolder sdCard = (await externalDevices.GetFoldersAsync()).FirstOrDefault();
StorageFile file = await sdCard.GetFileAsync("xyz.mp3"); // for D:\xyz.mp3
StorageFile file = await sdCard.GetFileAsync("XYZ\xyz.mp3"); // for D:\XYZ\xyz.mp3
答案 1 :(得分:2)
首先,确保您具有适当的功能集。如果您没有声明正确的CAP_ID,那么您所看到的错误就是您所看到的错误。这是一个截图:
关于文件路径,根据文件的存储位置,您可能需要使用双斜杠。我有一个类似的问题,我通过使用以下方法解决:
&#34; isostore:共享\\ FOLDERNAME \\ NameOfFile.mp3&#34;
您可以在my SO post here中查看整个过程。
答案 2 :(得分:1)
您需要使用access cache来存储对文件的访问权限而不是路径。这将允许您检索可以立即使用的StorageFile对象,并将帮助处理有关正在移动的文件的某些情况。
将文件存储在访问缓存中
StorageFile file; //Get a file
string mruToken = Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.Add(file, "20120716");
然后将令牌保存在某处。要从缓存中恢复文件:
StorageFile file = await Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.getFileAsync(mruToken);
只存储路径可以解决驱动器号更改等问题。这可以确保如果文件仍然可用,您的应用就可以获得它。