UnauthorizedAccessException while saving a file

点点圈 提交于 2019-12-07 04:38:01

问题


I have the following code in a Windows 8 C# app which fetches an image from a server and stores it:

        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;
    }

It appears that I randomly get errors on this particular line:

                var imageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(
         "test.png", CreationCollisionOption.ReplaceExisting);

It doesn't always happen, so I'm not sure how to pinpoint the issue. All the error details are here:

UnauthorizedAccessException was caught

Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at TestApp.MainPage.d__4.MoveNext() in d:\TestApp\TestApp\MainPage.xaml.cs:line 86


回答1:


Update - The "Access Denied" errors are being caused by multiple things.

The first cause has to do with the downloading of the image. It appears something in download code is holding open the file. I have simplified the download code below.

The second cause has to do with the BitmapImage object holding open the file. See this post for more info: Access Denied when deleting image file previously used in DataTemplate in WinRT

One way around the second issue is to use a stream instead of a Uri to initialize the BitmapImage.

Here is a version that works for me (your original code is also here, but commented out):

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;



回答2:


I have been facing the same problem when I downloaded the pdf document to LocalFolder file and tried to display it. I can't tell reliably why this is happening, but this little hack helped me to solve this:

Instead of using

try
{
  StorageFile storage = await ApplicationData.Current.LocalFolder.CreateFileAsync(
    fileName, CreationCollisionOption.ReplaceIfExists);

  //work with file
}
catch (Exception) { ... }

I now use this:

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
}



回答3:


If you have the option to use CreationCollisionOption.GenerateUniqueName instead of ReplaceExisting, try to use this.

At least it solved the problem for me.



来源:https://stackoverflow.com/questions/17000137/unauthorizedaccessexception-while-saving-a-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!