我正在使用ServiceStack作为我的Web框架,并尝试在管道上发送3 gig文件。下面是我试图用来发送文件的代码。它适用于小文件,但是当我尝试发送大文件时,应用程序会停止并且从不实际发送文件。
public IHttpResult Any(TilesRequest request)
{
var filename = request.Name.ToLower();
var filePath = HttpContext.Current.Server.MapPath(ConfigLookups.TilesDirectory + filename);
if (File.Exists(filePath))
{
Response.AddHeader("content-disposition", "attachment;filename=" + filename);
var stream = File.OpenRead(filePath);
return new HttpResult(stream, "application/x-sqlite3");
}
else
{
return new HttpError(System.Net.HttpStatusCode.NotFound, "File not found");
}
}
我也尝试过:
Response.TransmitFile(filePath);
然后我收到一条错误消息:
size参数必须介于0和最大Int32值之间。
关于如何正确发送这么大的文件的任何想法?
答案 0 :(得分:3)
Response.TransmitFile
只委托ASP.NET的TransmitFile,它是有效发送大文件的API - 它使用了一个高效的Win32 API,在其下面从错误描述中看起来只限于2 GB(2 ^ 32)的大小。目前尚不清楚是否在64位操作系统中解除了限制。
ASP.NET强加了其他限制(即ServiceStack本身不会增加任何限制)。此前一个主题显示了一些您可以尝试send large files with ASP.NET的提示。
这也适用于ServiceStack,因为它只是ASP.NET IHttpHandler
的包装器。您可以使用以下命令获取基础ASP.NET响应:
var aspResponse = base.Response.OriginalResponse as HttpResponseBase;
内置的ASP.NET httpRuntime请求限制也需要调整。
您还希望禁用缓冲以避免内置的2 ^ 32大小限制。 ASP.NET在启用压缩时默认执行此操作,因此您还要禁用此功能:
<system.webServer>
<urlCompression doStaticCompression="true" doDynamicCompression="false" />
</system.webServer>
但通常如果你超过2 ^ 32的限制,无论你做什么,你都可能会在ASP.NET中一次性发送这么多数据。
我正在寻找的流式传输大型文件的解决方案是使用ServiceStack的内置Partial Content Support。而不是在1个请求中流式传输大型文件,而是更改HttpClient以在多个请求中以块的形式获取文件。
return new HttpResult(new FileInfo(filePath), request.MimeType);
return new HttpResult(ms, "audio/mpeg");
以下是使用HttpUtils获取Partial Content from ServiceStack Services的一些示例,例如:
var url = "{0}/{1}".Fmt(BaseUrl, new TilesRequest { ... }.ToUrl());
var partialBytes = url.GetBytesFromUrl(
requestFilter: httpReq => httpReq.AddRange(Offset, ChunkSize),
responseFilter: httpRes => {
"Content-Length header {0}".Print(
httpRes.Headers["Content-Length"]);
});
您需要在循环中执行此操作以将所有部分字节响应拼接在一起。