【问题标题】:How to retrieve files from the windows phone (8.1) music library using path names?如何使用路径名从 windows phone (8.1) 音乐库中检索文件?
【发布时间】:2014-04-25 13:24:57
【问题描述】:

我让我的用户从音乐库中选择文件。之后,我将所选文件的路径存储在本地。现在我的问题是如何从这些路径以编程方式访问文件?以下是我尝试过的几件事。

假设我的路径名是 D:\Xyz\abc.mp3

StorageFolder S=KnownFolders.MusicLibrary;

备选方案 1:

StorageFile MyFile=await S.GetFileAsync("abc.mp3"); //找不到文件错误

// 我认为这不起作用,因为 GetFileAsync 方法只能从当前文件夹中获取文件

备选方案 2:

S=await S.GetFolderAsync("Xyz"); //之后我打算做GetFileAsync。但这也给出了一个找不到文件夹的错误。

最后我尝试了 S=await S.GetFolderAsync("D");

任何有关我如何访问该文件的帮助,甚至是实现我目标的替代方法都很棒!

P.S : StorageFile.GetFileFromPathAsync("D:\Xyz\abc.mp3") 说我没有访问权限。

【问题讨论】:

  • GetFileFromPathAsync 不保证在 Windows Phone 8.1 上保持对来自选取器的文件的访问。拒绝访问是预期的结果。要保持访问权限,您必须使用 Windows.Storage.AccessCache 命名空间。请参阅我的答案以了解保持对文件的访问权限的一种方法。

标签: windows windows-phone windows-phone-8.1


【解决方案1】:

(答案重建更清楚)

如果你在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 - 用于电话

D:\Music\Test\test2.mp3 - 用于 SD 卡

请记住,通过StorageFolder.GetFileAsync() 访问相对于 StorageFolder(它也适用于完整路径,请参阅下面的备注):

要检索的文件的名称(或相对于当前文件夹的路径)。

在这种情况下,要获取上述文件,您将使用以下文件名:test.mp3Test\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

已经给出结果:

  • 在第一种情况下,实际上是 Music 文件夹及其子文件夹中的 5 个文件,
  • 在第二种情况下 - 14 个文件位于:音乐库、SD 卡和电话中

您可以在调试模式下轻松查看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

【讨论】:

  • 我已经勾选了音乐库功能。我正在从库中获取所有文件并让用户选择它们。然后我存储文件路径,直到它很好。现在我想稍后在我的应用程序中访问这些文件。就像我说的 StorageFile file = await folder.GetFileAsync("fileName.mp3");不工作。而且我确信库中存在这样的文件,因为我从用户选择的 StorageFile 对象中获取了名称。一种简单的方法是每次都执行 GetFilesAsync(Query) 并在结果中搜索我的文件。但这会导致糟糕的表现。
  • @Aditya 我认为你不应该使用Path,而应该使用Name 和父文件夹。看StorageFolder folder = KnownFolders.MusicLibrary 让您可以访问音乐库 - 您应该 GetFiles 相对于它。我不确定记住路径或名称是否是一个好方法 - 看看音乐库可以在 SD 卡和手机内存中,用户可以在它们之间切换文件。您还应该检查用户是否没有删除文件。
  • 也试过用name,还是不行。并且没有发生删除、移动的情况,因为我是在我的手机/模拟器中进行的。
  • @Aditya 我已经在设备上尝试过了,它应该可以工作。我不明白 - 你是在模拟器还是设备上测试它?
  • 两者都做了。同样的错误。你能详细说明一下你的案例是什么吗?
【解决方案2】:

首先,确保您设置了适当的功能。如果您没有声明正确的 CAP_ID ,您将看到的错误。截图如下:

关于文件路径,根据文件的存储位置,您可能需要使用双斜杠。我有一个类似的问题,我通过使用以下方法解决了:

"isostore:shared\\folderName\\NameOfFile.mp3"

你可以在my SO post here看到整个过程。

【讨论】:

  • 它是一个 wp 8.1 应用程序,我已经勾选了音乐库功能。我正在从库中获取所有文件并让用户选择它们。然后我存储文件路径,直到它很好。现在我想稍后在我的应用程序中访问这些文件。是的,双斜线,还是一样的。
【解决方案3】:

您将希望使用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);

仅存储路径会使您遇到驱动器号更改等问题。这样可以确保如果文件仍然可用,您的应用可以获取它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多