在 WinRT 中检查项目中是不是存在文件
Posted
技术标签:
【中文标题】在 WinRT 中检查项目中是不是存在文件【英文标题】:Check if a file exists in the project in WinRT在 WinRT 中检查项目中是否存在文件 【发布时间】:2012-08-25 11:32:32 【问题描述】:我有一个 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
不存在。
起初我想使用 File.Exists()
的 WinRT 等效项,但似乎没有。不必去尝试打开文件并捕获错误的程度,我可以简单地检查文件是否存在,或者文件是否存在于项目中?
【问题讨论】:
您认为存在的资产实际上并不存在,这应该是例外。所以抓住异常。 @HansPassant 我认为他不认为它们存在。他提前知道它们有可能不存在。 非常同意@mydogisbox。 ExistsAsyncs() 自开发预览版以来一直在讨论,但尚未进入。我仍然很想听听背后的论点... 我只是在我的工具包中查看了类似的problem,并认为 Exists 方法不存在真是令人遗憾。关于竞争条件和方法的所有这些都是一种不好的做法——那些不应该改变并且实际上永远不会改变的应用程序资产呢?我想检查我的 appx 中的文件,但除了尝试打开这些文件并在它们丢失时捕获异常之外,我找不到其他选择,这真的很难看。也许 ResourceManager 可以帮助找到它们? 发现了一些关于 ResourceManager 的东西。您可以像这样检查应用程序包中的文件: ResourceManager.Current.MainResourceMap.ContainsKey("Files/Assets/Logo.png") 或 ResourceManager.Current.MainResourceMap.ContainsKey("Files/WinRTXamlToolkit/Themes/Generic.xaml" ) - 对于来自引用库的文件。这具有处理合格资源的额外好处 - 例如可能已在名称中添加了比例限定符但在基本不合格名称中不存在的图像 - 例如Logo.png 与 Logo.scale-100.png、Logo.scale-140.png、Logo.scale-180.png 等。 【参考方案1】:您可以使用here 中的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
编辑:
正如@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
【讨论】:
只需要 @Dave Bost 的回答中的 installedLocation 啊,是的。您可能需要使用适当的 URI 方案,例如:***.com/a/12020163/901059 他获取路径的方式会自动添加它。 就我所尝试的而言,这实际上不起作用。它会引发“找不到文件”异常。 @SergueiFedorov 然后发布关于您遇到的问题的帖子。显然,它至少对其他几个人有效。 Windows 上的文件名不区分大小写吗?我们不应该以不区分大小写的方式检查列表吗?【参考方案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.");
【讨论】:
以防万一其他人在为 Windows Phone 8.1 编写 WinRT 应用程序时偶然发现此问题,目前不支持 CommonFileQuery。【参考方案3】:BitmapImage
有一个 ImageFailed
事件,如果无法加载图像,则会触发该事件。这将让您尝试加载原始图像,然后在它不存在时做出反应。
当然,这需要您自己实例化BitmapImage
,而不是仅仅构建Uri
。
【讨论】:
【参考方案4】:c++ /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()));
【讨论】:
以上是关于在 WinRT 中检查项目中是不是存在文件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中的 WinRAR、7Zip、Zip、Tar、Winzip 中检查文件是不是存在