Downloading and saving a file Async in Windows Phone 8

匿名 (未验证) 提交于 2019-12-03 01:12:01

问题:

How can I download and save a file to IsolatedStorage asynchronously? I used WebClient first for the purpose, but I couldn't await till completion so I found some useful code here.

However, this is also not in complete format. I found the function:

public static Task DownloadFile(Uri url) {     var tcs = new TaskCompletionSource();     var wc = new WebClient();     wc.OpenReadCompleted += (s, e) =>     {         if (e.Error != null) tcs.TrySetException(e.Error);         else if (e.Cancelled) tcs.TrySetCanceled();         else tcs.TrySetResult(e.Result);     };     wc.OpenReadAsync(url);     return tcs.Task; } 

But how can I save this file to IsolatedStorage? Someone help me to complete this functionality!

回答1:

This, what har07 posted, should work. In case you need to extend your method a little, I would try to do something like this (though it is not tested, but should work):

(Rebuilt after comment - with Cancellation)

// first define Cancellation Token Source - I've made it global so that CancelButton has acces to it CancellationTokenSource cts = new CancellationTokenSource(); enum Problem { Ok, Cancelled, Other }; // results of my Task  // cancelling button event private void CancellButton_Click(object sender, RoutedEventArgs e) {    if (this.cts != null)         this.cts.Cancel(); }  // the main method - I've described it a little below in the text public async Task DownloadFileFromWeb(Uri uriToDownload, string fileName, CancellationToken cToken) {    try    {        using (Stream mystr = await DownloadFile(uriToDownload))            using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())            {            if (ISF.FileExists(fileName)) return Problem.Other;            using (IsolatedStorageFileStream file = ISF.CreateFile(fileName))            {                const int BUFFER_SIZE = 1024;                byte[] buf = new byte[BUFFER_SIZE];                 int bytesread = 0;                while ((bytesread = await mystr.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)                {                   cToken.ThrowIfCancellationRequested();                   file.Write(buf, 0, bytesread);                }            }        }        return Problem.Ok;     }     catch (Exception exc)     {        if (exc is OperationCanceledException)            return Problem.Cancelled;        else return Problem.Other;      } }  // and download private async void Downlaod_Click(object sender, RoutedEventArgs e) {    cts = new CancellationTokenSource();    Problem fileDownloaded = await DownloadFileFromWeb(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt", cts.Token);    switch(fileDownloaded)    {       case Problem.Ok:            MessageBox.Show("File downloaded");            break;       case Problem.Cancelled:            MessageBox.Show("Download cancelled");            break;       case Problem.Other:       default:            MessageBox.Show("Other problem with download");            break;     } } 

I've added Cancellation Token - it means that your download operation can be cancelled after Button.Click. On the other hand if await DownloadFile(uriToDownload) is Cancelled it automatically throws OperationCancelled - then you catch that exception and return adequate result.

I haven't run that code, but it may show the main idea.



回答2:

Try something like this (not tested) :

try {     using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())     {         IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile("fileNameHere");          BitmapImage bitmap = new BitmapImage();         var stream = await DownloadFile(new Uri("http://someuri.com", UriKind.Absolute));         bitmap.SetSource(stream);         WriteableBitmap wb = new WriteableBitmap(bitmap);          // Encode WriteableBitmap object to a JPEG stream.         Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);         fileStream.Close();     } } catch (Exception ex) {     //Exception handle appropriately for your app   } 

[Reference]



回答3:

In my opinion best way to use native implementation like this (Wrapping Begin/End asynchronous API):

var url = new Uri(UriString, UriKind.Absolute); var fileName = Path.GetFileName(url.LocalPath);  var w = WebRequest.CreateHttp(url); var response = await Task.Factory.FromAsync(w.BeginGetResponse, w.EndGetResponse, null); await response.GetResponseStream().CopyToAsync(new FileStream(ApplicationData.Current.LocalFolder.Path + @"\" + fileName, FileMode.CreateNew)); 


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