Answered by:
File Save / Open Conflict

Question
-
I am trying to download a file to local storage then open that file. The file saves okay and if I close/open the app the file works as expected. However, if I try to open the file without closing the app first I get E_ACCESSDENIED. It seems as though the file save is keeping a handle on the file but as far as I can tell I'm closing/disposing of everything I should be. What am I missing?
thanks.
HttpClient httpClient = new HttpClient();
// cleanup
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
// create a local file to save to
string filename = uri.Substring(uri.LastIndexOf("/") + 1, uri.Length - uri.LastIndexOf("/") - 1);
StorageFile imageFile = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
var ras = await imageFile.OpenAsync(FileAccessMode.ReadWrite);
// write the data to the file
DataWriter writer = new DataWriter(ras.GetOutputStreamAt(0));
writer.WriteBytes(await response.Content.ReadAsByteArrayAsync());
// close
await writer.StoreAsync();
await writer.FlushAsync();
writer.DetachStream();
response.Dispose();
await ras.FlushAsync();
writer.Dispose();
ras.Dispose();
Thursday, April 24, 2014 8:08 AM
Answers
-
I finally figured it out. The difference seems to be that I was creating the output stream inline and so didn't have a name to dispose of it with. This code works great to write a file and tidy everything up properly.
public async Task DownloadFile(string uri, StorageFolder folder)
{
try
{
// make the web call to get the file
HttpClient httpClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
// create a local file to save to
string filename = uri.Substring(uri.LastIndexOf("/") + 1, uri.Length - uri.LastIndexOf("/") - 1);
StorageFile file = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
using (var ras = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (var outStream = ras.GetOutputStreamAt(0))
{
using (DataWriter writer = new DataWriter(outStream))
{
writer.WriteBytes(await response.Content.ReadAsByteArrayAsync());
// close
await writer.StoreAsync();
await writer.FlushAsync();
writer.DetachStream();
await ras.FlushAsync();
// cleanup
response.Dispose();
writer.Dispose();
ras.Dispose();
}
}
}
}
catch (Exception exc)
{
string x = "y";
}
}- Marked as answer by Michael.OConnor Friday, April 25, 2014 12:36 PM
Friday, April 25, 2014 12:36 PM
All replies
-
how are you opening the file? i tried with the launcher, which worked great. do you have a demo case we can play with so we can help?
Microsoft Certified Solutions Developer - Windows Store Apps Using C#
Thursday, April 24, 2014 9:04 AM -
This is how I open the file. The call my GetFile function works find, it is the OpenAsync to get the stream that returns the E_ACCESSDENIED.
StorageFile audioFile = await App.GetFile(uri);
if(audioFile != null)
{
var stream = await audioFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
// kablooey!
}
public async static Task<StorageFile> GetFile(string uri)
{
string filename = uri.Substring(uri.LastIndexOf("/") + 1, uri.Length - uri.LastIndexOf("/") - 1);
StorageFolder folder = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFolderAsync("fileCache", CreationCollisionOption.OpenIfExists);
try
{
StorageFile file = await StorageFile.GetFileFromPathAsync(folder.Path + "\\" + filename);
return file;
}
catch (Exception exc)
{
return null;
}
}Thursday, April 24, 2014 7:01 PM -
can you post a sample so can see the entire flow?
Microsoft Certified Solutions Developer - Windows Store Apps Using C#
Friday, April 25, 2014 6:51 AM -
I finally figured it out. The difference seems to be that I was creating the output stream inline and so didn't have a name to dispose of it with. This code works great to write a file and tidy everything up properly.
public async Task DownloadFile(string uri, StorageFolder folder)
{
try
{
// make the web call to get the file
HttpClient httpClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
// create a local file to save to
string filename = uri.Substring(uri.LastIndexOf("/") + 1, uri.Length - uri.LastIndexOf("/") - 1);
StorageFile file = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
using (var ras = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (var outStream = ras.GetOutputStreamAt(0))
{
using (DataWriter writer = new DataWriter(outStream))
{
writer.WriteBytes(await response.Content.ReadAsByteArrayAsync());
// close
await writer.StoreAsync();
await writer.FlushAsync();
writer.DetachStream();
await ras.FlushAsync();
// cleanup
response.Dispose();
writer.Dispose();
ras.Dispose();
}
}
}
}
catch (Exception exc)
{
string x = "y";
}
}- Marked as answer by Michael.OConnor Friday, April 25, 2014 12:36 PM
Friday, April 25, 2014 12:36 PM