我遇到从web api到win forms app的大文件下载问题。在win form app上我使用HttpClient来获取数据。我在服务器端有以下代码:
[HttpPost]
[Route]
public async Task<HttpResponseMessage> GetBackup(BackupRequestModel request)
{
HttpResponseMessage response;
try
{
response = await Task.Run<HttpResponseMessage>(() =>
{
var directory = new DirectoryInfo(request.Path);
var files = directory.GetFiles();
var lastCreatedFile = files.OrderByDescending(f => f.CreationTime).FirstOrDefault();
var filestream = lastCreatedFile.OpenRead();
var fileResponse = new HttpResponseMessage(HttpStatusCode.OK);
fileResponse.Content = new StreamContent(filestream);
fileResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return fileResponse;
});
}
catch (Exception e)
{
logger.Error(e);
response = Request.CreateResponse(HttpStatusCode.InternalServerError);
}
return response;
}
在客户端:
private async void btnStart_Click(object sender, EventArgs e)
{
var requestModel = new BackupRequestModel();
requestModel.Username = txtUsername.Text;
requestModel.Password = txtPassword.Text;
requestModel.Path = txtServerPath.Text;
var client = new HttpClient();
var result = await client.PostAsJsonAsync("http://localhost:50116/api/backup", requestModel);
var stream = await result.Content.ReadAsStreamAsync();
var localPath = @"d:\test\filenew.bak";
var fileStream = File.Create(localPath);
stream.CopyTo(fileStream);
fileStream.Close();
stream.Close();
fileStream.Dispose();
stream.Dispose();
client.Dispose();
}
}
这实际上有效,但此程序的目的是获取超过3GB的大文件并将其保存到客户端。
我已经尝试过这个大小为630MB的文件,我注意到的是:当我用http客户端调用web api时,http客户端实际上在内存流中加载了630MB,从内存流加载到文件流,但是当我尝试加载一个不同的文件我得到OutOfMemoryException。发生这种情况是因为应用程序不会从先前加载的文件中释放内存。我可以在任务管理器中看到它持有635MB的ram内存。
我的问题是如何在不使用内存流的情况下直接将数据从HttpClient写入文件,或者换句话说,当HttpClient下载数据时如何将数据写入文件?
答案 0 :(得分:1)
要发出请求,请使用SendAsync重载,以便您指定HttpCompletionOption并使用ResponseHeadersRead
。您必须手动构建请求,而不使用PostAsJsonAsync
便捷方法。