此代码段尝试读取UWP应用允许位置之外的文件:
StorageFile sf2 = await StorageFile.GetFileFromPathAsync(Path.Combine("C:\\Temp", "spam.dat"));
抛出System.UnauthorizedAccessException,它被Visual Studio 2015调试器拦截并显示在一个漂亮的弹出窗口中:
整个文字如下:
类型' System.UnauthorizedAccessException'的例外情况发生在mscorlib.ni.dll但未在用户代码中处理
WinRT信息:无法访问指定的文件或文件夹(C:\ Temp \ spam.dat)。该项目不在应用程序可以访问的位置(包括应用程序数据文件夹,可通过功能访问的文件夹以及StorageApplicationPermissions列表中的持久项目)。验证文件未标记系统或隐藏文件属性。
类型' System.UnauthorizedAccessException'的例外情况发生在mscorlib.ni.dll但未在用户代码中处理
现在是另一个代码片段(此代码尝试读取已经打开的文件):
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(ApplicationData.Current.LocalFolder.Path);
StorageFile file = await folder.CreateFileAsync("spam.dat", CreationCollisionOption.ReplaceExisting);
Stream fs = await file.OpenStreamForWriteAsync();
StorageFile sf2 = await StorageFile.GetFileFromPathAsync(Path.Combine(ApplicationData.Current.LocalFolder.Path, "spam.dat"));
await sf2.OpenStreamForReadAsync();
调试器中的异常屏幕看起来完全不同:
其他信息:访问被拒绝。 (HRESULT异常:0x80070005(E_ACCESSDENIED))
我不明白调试器对这些异常的看法如何不同。在我的代码中,我需要了解获取UnauthorizedAccessException的原因 - 如果是因为文件被锁定以供阅读,因为它被另一个编写者占用(我可以稍后再试)或者由于其他原因,例如它在LocalFolder之外(并且它不值得重试)。我实际上正在开发一个将由UWP应用程序的开发人员使用的库,因此我不知道将给出哪个文件/文件路径,并且不能对权限,目录结构等做任何假设。我只是得到输入路径,如果发生任何事情,只能使用异常处理来理解原因。
因此,Visual Studio调试器以某种方式看到了差异,但我不知道如何以编程方式执行此操作。在两种情况下,InnerException都为null,HResult也是相同的(0x80070005)。
答案 0 :(得分:1)
如果您要将.NET库移植到UWP,可能它根本不依赖StorageFile
(在实现或公共接口中),所以我会继续使用.NET类型,它们有明显的错误(未经授权的访问与IO):
try
{
var f = File.OpenRead(@"d:\temp\foo.txt");
}
catch (UnauthorizedAccessException ex)
{
Debug.WriteLine(ex.Message);
}
try
{
var localPath = ApplicationData.Current.LocalFolder.Path;
var filename = Path.Combine(localPath, "foo.txt");
var f1 = File.OpenWrite(filename);
var f2 = File.OpenRead(filename);
}
catch (IOException ex)
{
Debug.WriteLine(ex.Message);
}
如果我运行您的示例代码,我不会使用StorageFile
获取写/读示例的任何异常(尽管我正在运行Windows 10 Creator更新的Insider Builds)。如果我尝试两次打开相同的文件进行书写,我会得到一个例外,但是也投影为IOException
:
try
{
var f = await StorageFile.GetFileFromPathAsync(@"d:\temp\foo.txt");
}
catch (UnauthorizedAccessException ex)
{
Debug.WriteLine(ex.Message);
}
try
{
var localFolder = ApplicationData.Current.LocalFolder;
var f1 = await localFolder.CreateFileAsync("foo.txt", CreationCollisionOption.ReplaceExisting);
var f2 = await localFolder.GetFileAsync("foo.txt");
var s1 = await f1.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.AllowOnlyReaders);
var s2 = await f2.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.AllowOnlyReaders);
}
catch (IOException ex)
{
Debug.WriteLine(ex.Message);
}
答案 1 :(得分:0)
亚历,
对于第二个,您正在使用IO流而不处理您尝试在同一文件上创建另一个流的上一个流。因此,它阻止您说未经授权的访问。我已经介绍了刷新流并处理流然后代码正在为我工作。以下是修改后的代码:
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(ApplicationData.Current.LocalFolder.Path);
StorageFile file = await folder.CreateFileAsync("spam.dat", CreationCollisionOption.ReplaceExisting);
Stream fs = await file.OpenStreamForWriteAsync();
fs.Flush();
fs.Dispose();
StorageFile sf2 = await StorageFile.GetFileFromPathAsync(Path.Combine(ApplicationData.Current.LocalFolder.Path, "spam.dat"));
var x = await sf2.OpenStreamForReadAsync();