PrisonMike PrisonMike - 17 days ago 5
C# Question

UnauthorizedAccessException at storageFile.OpenReadAsync

The user can take multiple pictures. These pictures are stored in ApplicationData.Current.LocalFolder:

folderBatch = await ApplicationData.Current.LocalFolder.CreateFolderAsync("Batch", CreationCollisionOption.OpenIfExists);


When the user takes a picture, this method is fired:

public async void GetAndProcessImage()
{
IBuffer ImageBuffer = null;

if (App.settings.ImageSource == MyImageSource.Camera)
ImageBuffer = await Camera.TakePhotoAsync();

// store in batch folder
IReadOnlyList<StorageFile> listFiles = await folderBatch.GetFilesAsync();
int iNumberOfFiles = listFiles.Count;
StorageFile fileTarget = await folderBatch.CreateFileAsync(string.Format("batch{0}.jpg", iNumberOfFiles));
IRandomAccessStream filestream = await fileTarget.OpenAsync(FileAccessMode.ReadWrite);
await filestream.GetOutputStreamAt(0).WriteAsync(ImageBuffer);
await filestream.FlushAsync();
}


The pictures are taken with this method, called by GetAndProcessImage above:

public async Task<IBuffer> TakePhotoAsync()
{
Debug.WriteLine("taking picture...");
InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();

if (mediaCapture.VideoDeviceController.FocusControl.Supported)
await mediaCapture.VideoDeviceController.FocusControl.FocusAsync();

try
{
await mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
}
catch (Exception e)
{
ExceptionHandler.Instance.HandleException(e);
}
IBuffer ibuffer = await StreamHelpers.StreamToIBuffer(stream);
return ibuffer;
}


When the user is done, he/she can push a push a button to start reading the batch files:

MyFile file = new KNFBFile(string.Format("{0}\\{1}.knfb", ApplicationData.Current.LocalFolder.Path, string.Format("Batch-{0:yyyyMMdd-hh-mm-ss-tt}", DateTime.Now)));
uint iCount = 0;
foreach (StorageFile filebatch in listFiles)
{
await App.converter.ConvertBatchJPG(filebatch);
IRandomAccessStream imagestream = await StreamHelpers.IBufferToStream(App.ocr.LastImageBuffer);
file.SavePage(iCount++, imagestream);
}


This method is now called:

public async Task ConvertBatchJPG(StorageFile fileSource)
{
IRandomAccessStream JPGStream = await fileSource.OpenReadAsync();


-->the method above (OpenReadAsync) causes the exception
...
}

Answer

You need to dispose the filestream and the outputstream you are retrieving:

StorageFile fileTarget = await folderBatch.CreateFileAsync(string.Format("batch{0}.jpg", iNumberOfFiles));
using(IRandomAccessStream filestream = await fileTarget.OpenAsync(FileAccessMode.ReadWrite))
{
    using(var outStream = filestream.GetOutputStreamAt(0))
    {
        await outStream.WriteAsync(ImageBuffer);
    }
    await filestream.FlushAsync();
 }

Since you are not altering the stream returned by OpenAsync(), you can also avoid creating an intermediary output stream:

using(IRandomAccessStream filestream = await fileTarget.OpenAsync(FileAccessMode.ReadWrite))
{
    await filestream .WriteAsync(ImageBuffer);
    await filestream.FlushAsync();
 }
Comments