在后期测试阶段,我注意到我的应用程序发送的文件大于2 gigs(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();
谢谢
<磷>氮编辑: 最终代码如下所示:
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();
答案 0 :(得分:3)
通常做的是这种情况是使用流下载文件。因此,在任何时间点,整个文件(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();
}
请参阅此回答 - Write PDF stream to response stream