Есть ли правильный способ получить файл по его пути?

У меня есть два файла с таким же именем в 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, файл с тем же именем существует и на SD-карте в папке "Видео".

В этой ситуации, когда вы вызываете первую строку в коде выше, вы получите два файла, чтобы их дифференцировать, система предоставляет FolderRelativeId, поэтому файлы с тем же именем могут существовать в одном "местоположении". Если вы посмотрите полный путь к каждой папке, у вас, вероятно, будет C:\Viedos\test.txt и второй D:\Videos\test.txt.

Теперь пользователь в первом запуске взял файл с FilePicker, и я вспомнил его путь, например D:\Videos\test.txt. Во втором запуске приложения я хотел бы иметь доступ к этому файлу, используя его путь (или другой метод, кроме ограниченного FutureAccessList). Раньше я делал это с помощью StorageFile.GetFileFromPathAsync(path); - кажется, что он начинает бросать UnauthorizedAccessException в W10.

Ответы

Ответ 1

Вы можете получить экземпляр 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

Ответ 2

Согласно этой документации от MS, приложения могут отказаться разрешить сохранение файлов на SD карта. В результате медиа-библиотеки могут быть разделены на внутреннее хранилище устройства и на SD-карту.

Если я получу это правильно, ваше решение будет:

  • Отключите функцию, упомянутую выше.
  • Теперь вы должны искать только локальное устройство, а не SD-карту
    • Это приведет к уникальным именам файлов в каждом каталоге
  • Если ваш прецедент требует поиска файла на SD-картах, теперь вы должны получить доступ к SD-карте и запросить файл здесь

Я не уверен, если накладные расходы на кодирование для доступа к SD-карте по отдельности, если они заслуживают повышения производительности, только запрашивая локальное хранилище.

Ответ 3

Когда вы открываете файл с файловым сборщиком в приложении Windows 8.1 (я предполагаю, что Windows 10 работает одинаково), вы получаете токен прав в эту папку, которая длится некоторое время или до тех пор, пока вы не покинете приложение. При повторном открытии приложения вам необходимо повторно получить токен в папке.

Прочитайте эту статью о StorageApplicationPermissions.

Ответ 4

Я предполагаю, что можно было бы рационализировать UnauthorizedAccessException при вызове StorageFile.GetFileFromPathAsync(path), считая, что у вас нет доступа к корневому букву диска из вашего приложения, поэтому перемещение структуры папок таким образом не разрешено. Это предположение, хотя.

Что касается вашей проблемы, почему вы не можете это сделать?

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

Где D:\Videos\test.txt - значение свойства .Path, которое вы захватили из файла, который пользователь выбрал с помощью сборщика.

Возможно, вы можете ожидать, что он будет немного медленнее, когда в VideoLibrary будут миллионы файлов.