【问题标题】:asp.net uploading big files: throws System.OutOfMemoryExceptionasp.net 上传大文件:抛出 System.OutOfMemoryException
【发布时间】:2015-11-25 15:59:00
【问题描述】:

我想通过 ASP.NET 将大文件上传到 WCF 服务。在 100 MB 没有问题之前,我的配置可以完美运行,但超过 100 MB 时会引发 System.OutOfMemoryException。

上传方法适用于 FileStream,但在此之前,我将文件保存到临时文件夹。不确定这是问题还是其他问题。我添加了我的控制器的代码,它负责调用 wcf 服务。

[HttpPost]
    public ActionResult Upload()
    {
        if (Request.Files.Count > 0)
        {
            var file = Request.Files[0];

            if (file != null && file.ContentLength > 0)
            {
                string fileName = Path.GetFileName(file.FileName);
                var path = Path.Combine(Server.MapPath("~/App_Data/Images"), fileName);

                file.SaveAs(path);

                FileStream fsSource = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);

                TileService.TileServiceClient client = new TileService.TileServiceClient();
                client.Open();
                client.UploadFile(fileName, fsSource);
                client.Close();

                fsSource.Dispose();
                if (System.IO.File.Exists(path))
                {
                    System.IO.File.Delete(path);
                }
            }
        }

        return RedirectToAction("");
    }

方法是这样调用的:

@using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="FileUploader" />
<br />
<input type="submit" name="Submit" id="Submit" value="Upload file" />
}

在 ASP.NET web.config 中,我已经设置了以下内容:executionTimeout、maxRequestLength、requestLengthDiskThreshold、maxAllowedContentLength。我添加了配置的绑定部分。

<basicHttpBinding>
    <binding name="BasicHttpBinding_ITileService"
      closeTimeout="24:01:00" openTimeout="24:01:00" receiveTimeout="24:10:00" sendTimeout="24:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="4294967295" maxBufferSize="2147483647" maxReceivedMessageSize="4294967295" textEncoding="utf-8" transferMode="Streamed" useDefaultWebProxy="true" messageEncoding="Text">
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
  </basicHttpBinding>

【问题讨论】:

  • 您可以尝试使用 Request.Files[0].InputStream 分块读取它

标签: c# asp.net asp.net-mvc wcf out-of-memory


【解决方案1】:

问题不在我认为的代码中。 ASP.NET 项目托管在 IIS Express 而不是本地 IIS 中。由于我在项目属性中进行了更改,因此一切正常。

我现在正在使用 @nimeshjm 的代码。感谢您的帮助!

【讨论】:

    【解决方案2】:

    您可以尝试使用 Request.Files[0].InputStream 分块读取它

    类似的东西:

        public ActionResult Upload()
        {
            if (Request.Files.Count > 0)
            {
                var file = Request.Files[0];
    
                if (file != null && file.ContentLength > 0)
                {
                    string fileName = Path.GetFileName(file.FileName);
                    var path = Path.Combine(Server.MapPath("~/App_Data/Images"), fileName);
    
                    using (var fs = new FileStream(path, FileMode.OpenOrCreate))
                    {
                        var buffer = new byte[1024];
                        int count;
                        while ((count = file.InputStream.Read(buffer, 0, 1024)) > 0)
                        {
                            fs.Write(buffer, 0, count);
                        }
                    }
    
                    FileStream fsSource = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
    
                    TileService.TileServiceClient client = new TileService.TileServiceClient();
                    client.Open();
                    client.UploadFile(fileName, fsSource);
                    client.Close();
    
                    fsSource.Dispose();
                    if (System.IO.File.Exists(path))
                    {
                        System.IO.File.Delete(path);
                    }
                }
            }
    
            return RedirectToAction("");
        }
    

    【讨论】:

    • 可能是个好主意,但它写道: System.Web.dll 中发生了“System.ArgumentException”类型的异常,但未在用户代码中处理附加信息:目标数组不够长.检查 destIndex 和长度,以及数组的下限。有任何想法吗? :-/
    • while ((count += file.InputStream.Read(buffer, count, 1024)) > 0) 不确定 byte[1024] 是否足够?我应该能够上传最多 2 GB 的文件。我用 270 MB 的文件进行了测试。
    • 原始示例中的一个小错误 :) 我已经更新了示例,试一试。
    • 现在您的代码适用于小文件(测试为 33 MB),但我仍然收到 System.OutOfMemoryException 的大文件(测试为 270 MB):(
    • 哪一行抛出异常?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 2021-12-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多