Reputation: 29792
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.
Upvotes: 15
Views: 2431
Reputation: 698
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
Upvotes: 2
Reputation: 2260
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.
Upvotes: 0
Reputation: 1041
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.
Upvotes: 0
Reputation: 6046
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:
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.
Upvotes: 0