MVC 4.5.2响应.WriteFile大于2gb
本文关键字:WriteFile 大于 2gb 响应 MVC | 更新日期: 2023-09-27 18:11:31
在后期测试阶段,我注意到一个问题,我的应用程序发送的文件大于2 gb (Int32.MaxValue)。有什么简单的方法可以补救吗?这些是大的高清mov电影文件。我使用了Response。WriteFile在我的控制器,以确保浏览器不打开任何文件(大多数是大的视频文件,没有被浏览器打开,但不是全部),并强制下载以及做一些记录。
现在我唯一的选择是使用ajax做基于javascript的日志记录,并直接链接到大型mov文件,但我想避免在开发过程中更改我的日志记录方法。我真的希望所有的链接都能使用一种方法来记录,无论它们是大的mov文件还是需要使用writefile发送的文件,这样浏览器就不会为了简单起见而打开它们。但是我似乎没有太多的选择。
阻止这样的大文件传输背后的逻辑是什么?在堆栈跟踪中,我看到到处都是Int64大小而不是Int32,所以为什么它不工作?
我正在使用最新的(?)MVC(4.5.2)和VS2015.
这是我请求一个大文件时得到的错误:
[ArgumentOutOfRangeException: The size parameter must be between zero and the maximum Int32 value.
Parameter name: size
Actual value was 4563025348.]
System.Web.HttpFileResponseElement..ctor(String filename, Int64 offset, Int64 size, Boolean isImpersonating, Boolean useTransmitFile, Boolean supportsLongTransmitFile) +3824261
System.Web.HttpWriter.WriteFile(String filename, Int64 offset, Int64 size) +119
System.Web.HttpResponse.WriteFile(String filename, Boolean readIntoMemory) +359
System.Web.HttpResponseWrapper.WriteFile(String filename) +30
这是控制器代码的相关部分
Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
Response.WriteFile(filePath);
Response.End();
谢谢
n .
编辑:最终代码看起来像这样:
using (FileStream fs = new FileStream(serverPath, FileMode.Open))
{
byte[] buffer = new byte[4096];
int count = 0;
Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
while ((count = fs.Read(buffer, 0, buffer.Length)) > 0)
{
Response.OutputStream.Write(buffer, 0, count);
Response.Flush();
}
}
HttpContext.ApplicationInstance.CompleteRequest();
在这种情况下通常做的是使用流下载文件。因此,在任何时候,整个文件(2GB!)都不会加载到内存中。试想一下,如果同时只有100个用户请求该文件,这将需要多少内存量。
你应该做的是通过流(FileStream
)读取文件,并将该流直接写入用户的响应。
像这样
//assuming you have your FileStream handle already - named fs
byte[] buffer = new byte[4096];
long count = 0;
while ((count = fs.Read(buffer, 0, buffer.Length)) > 0)
{
response.OutputStream.Write(buffer, 0, count);
response.Flush();
}
查看答案-将PDF流写入响应流