简体   繁体   中英

Is there any right way to get a file by its Path?

I've two files with the same name in KnownFolders.VideosLibrary , in this case I cannot access file by its Name hence it will return only the first one. Therefore is there any other way to get the file other that parsing all files in folder?

// 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");

I'm aware of FutureAccessList , but it can hold only up to 1000 files, what is not enough for me.


Some clarification after request:

For example lets consider that app run on phone with SD card. I've one file in Videos in phone's memory with name test.txt , the file with the same name exists also on SD card in Videos folder.

In this situation when you call the first line in code above, you will get two files, to differentiate them system provides FolderRelativeId , so files with the same name can exist in one 'location'. If you take a look at the full path of each folder one will likely have C:\\Viedos\\test.txt and the second D:\\Videos\\test.txt .

Now user on the first run picked a file with FilePicker and I've remembered its path for example D:\\Videos\\test.txt . On the second run of the app I would like to have access to this file by using its path (or other method apart from limited FutureAccessList ). In the past I used to do it by StorageFile.GetFileFromPathAsync(path); - by it seems that it starts throwing UnauthorizedAccessException in W10 .

You can get the instance of IStorageFile by this.

// 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

According to this documentation from MS, that apps can opt out of allowing files to be stored on the SD card. As a result, the media libraries can be split across the device's internal storage and the SD card .

If I get this right, your solution would be:

  • Opt out the feature mentioned above
  • You should now only search on the local device, not the SD card
    • This will result in unique file names in each directory
  • If your use-case requires to search for the file on SD cards as well, you now have to access the SD card , and query the file here

I'm not sure, if the coding overhead of accessing the SD card separately, if worth the performance gain by only querying the local storage.

When you open a file with a file picker in a Windows 8.1 app (I'm assuming Windows 10 works the same way) you are obtaining a rights token to that folder that lasts for a period of time, or until you quit the application. When you reopen the application, you have to re-obtain a token to the folder.

Read this article about the StorageApplicationPermissions object.

I guess one could rationalize the UnauthorizedAccessException thrown when calling StorageFile.GetFileFromPathAsync(path) by considering that you don't have access to a root drive letter from your app, so navigating the folder structure that way is not allowed. It's a guess though.

As for your problem, why aren't you able to do this?

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

Where D:\\Videos\\test.txt is the .Path property value that you grabbed from the file that the user selected using the picker.

Perhaps you can expect it to be a little slower when there are millions of files on the VideosLibrary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM