6

У меня есть следующий код в ОС Windows 8 C# приложение, которое получает изображение с сервера и сохраняет его:UnauthorizedAccessException при сохранении файла

 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 был пойман

Доступ запрещен. (Исключение из 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

ответ

6

Обновление - "Доступ запрещен" ошибки вызванных несколькими вещами.

Первая причина связана с загрузкой изображения. Кажется, что что-то в загружаемом коде держит открытый файл. Я упростил код загрузки ниже.

Вторая причина связана с объектом BitmapImage, открывающим файл. Смотрите эту должность для получения дополнительной информации: Access Denied when deleting image file previously used in DataTemplate in WinRT

Один путь вокруг второго вопроса является использование 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; 
+0

Хм, теперь я получаю UnauthorizedAccessException (доступ запрещен. (Исключение из HRESULT: 0x80070005 (E_ACCESSDENIED))) в 'var stream = await imageFile.OpenAsync (Windows.Storage.FileAccessMode.Read);'. Вероятно, на этот раз выдаются разрешения? Есть идеи? :/ – ReignOfComputer

+2

@ReignOfComputer - см. Мое обновленное сообщение. Это изменилось совсем немного. –

+0

Омг, который это так благодарит!Ты восхитителен! : D – ReignOfComputer

1

Я был сталкивается с той же проблемой, когда я загрузил документ в формате 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 
} 
1

Если у вас есть возможность использования CreationCollisionOption. GenerateUniqueName вместо ReplaceExisting, попробуйте использовать это.

По крайней мере, он решил проблему для меня.