我想将zip文件直接从服务器保存到隔离存储中,但是我面临的问题是当我尝试使用以下代码保存时,由于我的文件大小有时>150 MB,因此出现内存不足异常。所以我在这里发布了一个问题,建议是
您可以将这样的文件直接下载到隔离存储,但如果您想将其放入内存 - 可能会出现问题。
那么如何在不保存到内存的情况下将文件从服务器直接保存到独立存储。我使用的代码发布在这里
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);
}
}
}
}
然后也许可以尝试这样的方法 - 使用 HttpWebRequest 来做:
- 1. 首先使用可等待的 GetResponseAsync 扩展您的 HttpWebRequest - WP 缺少此方法,但使用 TaskCompletitionSource,您可以编写自己的实现。在命名空间中,创建一个静态类:
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. 然后修改您的代码以使用它:
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.并下载:
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;
}
}
当我有我的WebResponse时,我从中获取一个流,然后异步读取它。
请注意,我还没有测试上面的代码,但希望它能给你一些想法,这是如何工作的。
就像首先将原始数据保存在 Sqlite 文件中并在代码中使用,然后调用服务器对数据所做的更改并获取这些更新,这样您就不必一次又一次地下载数据。此外,如果您必须在每次调用时下载数据,则可以使用 sqlite 或 linq。