Есть ли правильный способ получить файл по его пути?
У меня есть два файла с таким же именем в 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 будут миллионы файлов.