如何在ASP.NET MVC中上传1.25GB大小的文件

5

我的客户通过应用上传超过1GB的文件。我知道使用asp.net MVC应用程序只能上传100MB。

 public static byte[] ReadStream(Stream st)
     {
         st.Position = 0;
         byte[] data = new byte[st.Length];
         .
         .
         .        
         . 
}

我在byte[] data = new byte[st.Length];处遇到错误,因为st.Length=1330768612。错误信息是“抛出了类型为'System.OutOfMemoryException'的异常。”
有没有办法上传超过1GB的文件?为什么我们可以在webconfig中定义maxRequestLength = 0-2097151?

3
你怎么知道只能上传100MB? - Noldorin
@Noldorin - +1,我也正想问这个问题... - Krunal
我还没有尝试上传大于20-30mb的文件。所以不知道它是否支持1 gb。因此,对于更大的上传,请寻找一些第三方工具/资源。 - user240141
@Noldorin.. 我曾经在 MSDN 上读过这篇文章。 - Pankaj
好的。你有测试过上传大于100MB的文件并查看会发生什么吗?它会默默失败,还是会出现错误? - Noldorin
6个回答

3

我认为你需要使用正确的工具来完成这项工作。Http协议并不适用于像这样传输大文件。为什么不考虑使用ftp协议,然后再围绕它构建一个Web界面呢。


我同意,这个需求需要使用不同的工具。 - Martin Clarke
你不觉得这样可能会引发问题吗?如果你想使用一个将文件放置在FTP上的网络界面,你仍然会使用http。如果你想要实现这个功能,你必须使用插件(如Java小程序、Flash、SilverLight,但这并不容易),因为你不能依赖浏览器来上传到FTP(据我所知,只有IE可以用于在FTP上放置文件,因为它可以使用explorer.exe来显示FTP内容)。另一个缺点是你可能需要让用户在你的FTP上获得访问权限(或以某种方式提供设置)。 - Gertjan
有整个应用程序类别,如文档管理、WCM、各种在线服务,需要上传大文件并且不能使用FTP。此外,问题不在于工具或MVC,而只是几行代码中的一个错误。 - Panagiotis Kanavos

1

您看到的错误提示表明服务器没有足够的内存来处理内存中的文件。请验证您的服务器是否有足够的内存来分配这样一个大的数组/文件。

您也可以尝试处理流的块。如果您收到了内存不足的消息,那么说明文件已经发送到服务器,但服务器无法处理该文件。

我真的认为这与您分配的数组大小有关。它只是无法适应您机器的内存(或.NET分配的内存)。


1

错误提示说,您在尝试在内存中分配1GB字节数组时已经用完了内存。这与MVC无关。您还应该注意,32位进程的内存限制为2GB。如果您的服务器运行32位操作系统,并且您将其中1GB用于单个上传,您将很快耗尽可用内存。

不要尝试将整个流读入内存,而是使用Stream.Read以合理大小的缓冲区读取数据,并使用Write调用将块存储到文件流中。这样不仅可以避免OutOfMemoryExceptions,而且代码也会运行得更快,因为您不必等待加载整个1GB再将其存储到文件中。

代码可以简单地如下所示:

public static  void SaveStream(Stream st,string targetFile)
{
    byte[] inBuffer = new byte[10000];

    using(FileStream outStream=File.Create(targetFile,20000))
    using (BinaryWriter wr = new BinaryWriter(outStream))
    {
        st.Read(inBuffer, 0, inBuffer.Length);
        wr.Write(inBuffer);
    }
}

您可以调整缓冲区大小来平衡吞吐量(上传和保存速度)与可扩展性(可以处理的客户端数量)。


0

我记得在一个旧项目中,我们不得不想出一种方法,允许用户上传2-4GB的文件到我们的ASP.NET Web应用程序。

如果我没记错的话,我们使用了“文件上传控件”,并编辑了web.config以允许更大的文件大小:

<system.web>
     <httpRuntime executionTimeout="2400" maxRequestLength="40960" />
</system.web>

另一个选择是使用 HttpModule:

http://dotnetslackers.com/Community/blogs/haissam/archive/2008/09/12/upload-large-files-in-asp-net-using-httpmodule.aspx


谢谢 @@Dal.. 我已经在配置文件中设置了以下内容 <httpRuntime executionTimeout="7200" maxRequestLength="2097151"/>。 - Pankaj
@Pankaj - 噢,抱歉,忘记了你最后一行的内容 :) - Dalbir Singh

0

我建议使用FTP或编写一个小型桌面应用程序。 HTTP并不打算用来发送如此大的文件。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接