使用 System.Net.WebClient 上传文件时出现 OutOfMemoryException

OutOfMemoryException while uploading file with System.Net.WebClient

我想使用 http post 上传文件。以下方法工作正常但文件 >1GB 我得到 OutOfMemoryExceptions

我根据 AllowWriteStreamBufferingSystem.Net.WebRequest 找到了一些 solutions 但在这种情况下这似乎没有帮助,因为我需要用 System.Net.WebClient 来解决它。

抛出异常时我的应用程序的内存使用量始终约为 ~500MB

string file = @"C:\test.zip";
string url = @"http://foo.bar";
using (System.Net.WebClient client = new System.Net.WebClient())
{
    using (System.IO.Stream fileStream = System.IO.File.OpenRead(file))
    {
        using (System.IO.Stream requestStream = client.OpenWrite(new Uri(url), "POST"))
        {
            byte[] buffer = new byte[16 * 1024];
            int bytesRead;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                requestStream.Write(buffer, 0, bytesRead);
            }
        }
    }
}

我需要更改什么才能避免此错误?

经过 1 天的尝试,我找到了解决此问题的方法。

也许这会对一些未来的访客有所帮助

string file = @"C:\test.zip";
string url = @"http://foo.bar";
using (System.IO.Stream fileStream = System.IO.File.OpenRead(file))
{
    using (ExtendedWebClient client = new ExtendedWebClient(fileStream.Length))
    {
        using (System.IO.Stream requestStream = client.OpenWrite(new Uri(url), "POST"))
        {
            byte[] buffer = new byte[16 * 1024];
            int bytesRead;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                requestStream.Write(buffer, 0, bytesRead);
            }
        }
    }
}

扩展WebClient方法

private class ExtendedWebClient : System.Net.WebClient
{
    public long ContentLength { get; set; }
    public ExtendedWebClient(long contentLength)
    {
        ContentLength = contentLength;
    }

    protected override System.Net.WebRequest GetWebRequest(Uri uri)
    {
        System.Net.HttpWebRequest hwr = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
        hwr.AllowWriteStreamBuffering = false; //do not load the whole file into RAM
        hwr.ContentLength = ContentLength;
        return (System.Net.WebRequest)hwr;
    }
}