保存文件时出现UnauthorizedAccessException异常
本文关键字:UnauthorizedAccessException 异常 保存文件 | 更新日期: 2023-09-27 18:17:34
我在Windows 8 c#应用程序中有以下代码,它从服务器获取图像并存储它:
private async Task httpFetcher()
{
HttpClient httpClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Get, "http://www.example.com/fakeImageRotator.php"); // FOR EXAMPLE
HttpResponseMessage response = await httpClient.SendAsync(request,
HttpCompletionOption.ResponseHeadersRead);
Uri imageUri;
BitmapImage image = null;
try
{
var imageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(
"test.png", CreationCollisionOption.ReplaceExisting);
var fs = await imageFile.OpenAsync(FileAccessMode.ReadWrite);
DataWriter writer = new DataWriter(fs.GetOutputStreamAt(0));
writer.WriteBytes(await response.Content.ReadAsByteArrayAsync());
await writer.StoreAsync();
writer.DetachStream();
await fs.FlushAsync();
writer.Dispose();
if (Uri.TryCreate(imageFile.Path, UriKind.RelativeOrAbsolute, out imageUri))
{
image = new BitmapImage(imageUri);
}
}
catch (Exception e)
{
return;
}
image1.Source = image;
}
似乎我在这一行随机得到错误:
var imageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(
"test.png", CreationCollisionOption.ReplaceExisting);
这种情况并不总是发生,所以我不确定如何确定问题所在。所有的错误细节在这里:
UnauthorizedAccessException was caught
访问被拒绝。HRESULT异常:0x80070005(E_ACCESSDENIED))System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务在System.Runtime.CompilerServices.TaskAwaiter ' 1.GetResult()在TestApp.MainPage.d__4.MoveNext(d: ' TestApp ' TestApp ' MainPage.xaml.cs: 86行
更新- "Access Denied"错误是由多种原因引起的。
第一个原因与图像的下载有关。下载代码中似乎有什么东西阻止打开文件。我已经简化了下面的下载代码:
第二个原因与持有打开文件的BitmapImage
对象有关。在WinRT中删除以前在DataTemplate中使用的图像文件时被拒绝访问
解决第二个问题的一种方法是使用stream
而不是Uri
来初始化BitmapImage
。
这是一个适合我的版本(你的原始代码也在这里,但被注释掉了):
var imageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(
"test.png", CreationCollisionOption.ReplaceExisting);
/*
var fs = await imageFile.OpenAsync(FileAccessMode.ReadWrite);
DataWriter writer = new DataWriter(fs.GetOutputStreamAt(0));
writer.WriteBytes(await response.Content.ReadAsByteArrayAsync());
await writer.StoreAsync();
writer.DetachStream();
await fs.FlushAsync();
writer.Dispose();
if (Uri.TryCreate(imageFile.Path, UriKind.RelativeOrAbsolute, out imageUri))
{
image = new BitmapImage(imageUri);
}
*/
var fs = await imageFile.OpenStreamForWriteAsync();
await response.Content.CopyToAsync(fs);
await fs.FlushAsync();
// you may want to have this Dispose as part of a
// finally block (try/ catch/ finally)
fs.Dispose();
var bs = await imageFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
image = new BitmapImage();
image.SetSource(bs);
...
image1.Source = image;
当我将pdf文档下载到LocalFolder文件并试图显示它时,我一直面临同样的问题。我不能确切地告诉为什么会发生这种情况,但是这个小技巧帮助我解决了这个问题:
不使用
try
{
StorageFile storage = await ApplicationData.Current.LocalFolder.CreateFileAsync(
fileName, CreationCollisionOption.ReplaceIfExists);
//work with file
}
catch (Exception) { ... }
我现在用这个:
StorageFile storage = null;
try
{
//First try to get the file
storage = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
}
catch (Exception)
{
//Ignore this exception
}
try
{
//If the storage file is still null, create it
if (storage == null)
storage = await ApplicationData.Current.LocalFolder.CreateFileAsync(
fileName, CreationCollisionOption.OpenIfExists);
//Work with file
}
catch (Exception)
{
//Process exception
}
如果您有使用CreationCollisionOption的选项。GenerateUniqueName代替ReplaceExisting,尝试使用这个
至少为我解决了这个问题。