Подтвердить что ты не робот

Проверьте, существует ли файл в проекте в WinRT

У меня есть проект WinRT Metro, который отображает изображения на основе выбранного элемента. Однако некоторые из выбранных изображений не будут существовать. То, что я хочу сделать, - это ловушка в случае, когда они не существуют и отображают альтернативу.

Вот мой код:

internal string GetMyImage(string imageDescription)
{
    string myImage = string.Format("Assets/MyImages/{0}.jpg", imageDescription.Replace(" ", ""));

    // Need to check here if the above asset actually exists

    return myImage;
}

Примеры вызовов:

GetMyImage("First Picture");
GetMyImage("Second Picture");

Итак, Assets/MyImages/SecondPicture.jpg существует, но Assets/MyImages/FirstPicture.jpg не работает.

Сначала я подумал об использовании эквивалента WinRT File.Exists(), но, похоже, не существует. Не пытаясь открыть файл и поймать ошибку, могу ли я просто проверить, существует ли файл, или файл существует в проекте?

4b9b3361

Ответ 1

Вы можете использовать GetFilesAsync из здесь для перечисления существующих файлов. Это кажется разумным, поскольку у вас есть несколько файлов, которые могут не существовать.

Получает список всех файлов в текущей папке и ее подпапках. Файлы фильтруются и сортируются на основе указанного CommonFileQuery.

var folder = await StorageFolder.GetFolderFromPathAsync("Assets/MyImages/");
var files = await folder.GetFilesAsync(CommonFileQuery.OrderByName);
var file = files.FirstOrDefault(x => x.Name == "fileName");
if (file != null)
{
    //do stuff
}

Edit:

Как отметил @Filip Skakun, диспетчер ресурсов имеет сопоставление ресурсов, на которое вы можете позвонить ContainsKey, который имеет преимущество проверки на наличие квалифицированных ресурсов (например, локализованного, масштабированного и т.д.).

Изменить 2:

В Windows 8.1 появился новый метод получения файлов и папок:

var result = await ApplicationData.Current.LocalFolder.TryGetItemAsync("fileName") as IStorageFile;
if (result != null)
    //file exists
else
    //file doesn't exist

Ответ 2

Есть два способа справиться с этим.

1) Поймайте FileNotFoundException при попытке получить файл:

 Windows.Storage.StorageFolder installedLocation = 
     Windows.ApplicationModel.Package.Current.InstalledLocation;
 try
 {
     // Don't forget to decorate your method or event with async when using await
     var file = await installedLocation.GetFileAsync(fileName);
     // Exception wasn't raised, therefore the file exists
     System.Diagnostics.Debug.WriteLine("We have the file!");
 }
 catch (System.IO.FileNotFoundException fileNotFoundEx)
 {
     System.Diagnostics.Debug.WriteLine("File doesn't exist. Use default.");
 }
 catch (Exception ex)
 {
     // Handle unknown error
 }

2), как рекомендует mydogisbox, используя LINQ. Хотя метод, который я тестировал, несколько отличается:

 Windows.Storage.StorageFolder installedLocation =
     Windows.ApplicationModel.Package.Current.InstalledLocation;
 var files = await installedLocation.GetFilesAsync(CommonFileQuery.OrderByName);
 var file = files.FirstOrDefault(x => x.Name == fileName);
 if (file != null)
 {
    System.Diagnostics.Debug.WriteLine("We have the file!");
 }
 else
 {
    System.Diagnostics.Debug.WriteLine("No File. Use default.");
 }

Ответ 3

BitmapImage имеет ImageFailed событие который срабатывает, если изображение не может быть загружено. Это позволит вам попытаться загрузить исходное изображение, а затем отреагировать, если оно там отсутствует.

Конечно, для этого требуется создать экземпляр BitmapImage самостоятельно, а не просто создать Uri.

Ответ 4

Проверка проверки доступности ресурсов для С++/cx (протестирована с помощью Windows Phone 8.1):

std::wstring resPath = L"Img/my.bmp";
std::wstring resKey = L"Files/" + resPath;
bool exists = Windows::ApplicationModel::Resources::Core::ResourceManager::Current->MainResourceMap->HasKey(ref new Platform::String(resKey.c_str()));