Save to isolated storage directly in WP8

喜你入骨 提交于 2019-12-02 11:58:27

问题


I want to save a zip file directly to isolated storage from server , But the problem i am facing was when i try to save using the below code , i get out of memory exception since my file size is > 150 MB some times. So i posted a question here and the suggestion was

you can download such a file directly to IsolatedStorage, but if you want to put that into Memory - there can be a problem.

So how can i save a file from server directly to isolated storage without saving to memory . The code i used is posted here

client = new WebClient();
    client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
    client.OpenReadAsync(new Uri(fileurl), objRef);

    private async void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {

            var file = IsolatedStorageFile.GetUserStoreForApplication();
            if (!file.DirectoryExists("Folderpath/Files"))
            {
                file.CreateDirectory("Folderpath/Files");
            }
            string hpubFile = "/Folderpath/Files/fileName" ;
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(hpubFile, System.IO.FileMode.OpenOrCreate, FileAccess.ReadWrite, file))
            {
                byte[] buffer = new byte[1024];
                while (e.Result.Read(buffer, 0, buffer.Length) > 0)
                {
                    stream.Write(buffer, 0, buffer.Length);
                }
            }
        }
    }

回答1:


Then maybe try such an approach - do it with HttpWebRequest:

    1. First extend your HttpWebRequest with awaitable GetResponseAsync - WP lacks this method, but with TaskCompletitionSource you can write your own implementation. Somwhere in your Namespace, make a static class:
public static class Extensions
{
    public static Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest webRequest)
    {
        TaskCompletionSource<HttpWebResponse> taskComplete = new TaskCompletionSource<HttpWebResponse>();
        webRequest.BeginGetResponse(
            asyncResponse =>
            {
                try
                {
                    HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
                    HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
                    taskComplete.TrySetResult(someResponse);
                }
                catch (WebException webExc)
                {
                    HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
                    taskComplete.TrySetResult(failedResponse);
                }
                catch (Exception exc) { taskComplete.SetException(exc); }
            }, webRequest);
        return taskComplete.Task;
    }
}

    2. Then modify your code to use it:
CancellationTokenSource cts = new CancellationTokenSource();
enum Problem { Ok, Cancelled, Other };

public async Task<Problem> DownloadFileFromWeb(Uri uriToDownload, string fileName, CancellationToken cToken)
{
    try
    {
        HttpWebRequest wbr = WebRequest.CreateHttp(uriToDownload);
        wbr.Method = "GET";
        wbr.AllowReadStreamBuffering = false;
        WebClient wbc = new WebClient();

        using (HttpWebResponse response = await wbr.GetResponseAsync())
        {
            using (Stream mystr = response.GetResponseStream())
            {
                using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
                  {
                      if (ISF.FileExists(fileName)) return Problem.Other;
                      using (IsolatedStorageFileStream file = ISF.CreateFile(fileName))
                      {
                          const int BUFFER_SIZE = 100 * 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; 
      }
  }

    3. 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("Problem with download");
              break;
          case Problem.Cancelled:
              MessageBox.Show("Download cancelled");
              break;
          case Problem.Other:
          default:
              MessageBox.Show("Other problem with download");
              break;
      }
  }

As I've my WebResponse, I get a stream from it and then read it async.
Please be aware that I've not tested the code above, but hopefuly it may give you some ideas how this can work.




回答2:


Yes you can and you can do it like first save original data in Sqlite file and use in the code and then call server for changes which are made in the data and get those updates so you don't have to download data again and again.. Also if you have to download data on each call then you can use sqlite or linq.



来源:https://stackoverflow.com/questions/21671157/save-to-isolated-storage-directly-in-wp8

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