如何使用C#将大文件上传到另一个HTTP服务?

时间:2019-04-22 06:01:12

标签: c# .net file-upload .net-core

我正在研究C#在.NET Core 2.2上编写的项目。在我的代码中,我需要将一个大文件(大约2GB)上传到远程HTTP服务器。

我对远程服务器不负责。我只负责上传逻辑。

在C#中通过HTTP上传大型本地文件的最佳做法是什么?

我尝试了以下代码

https://github.com/AiursoftWeb/Nexus/blob/master/Pylon/Services/HTTPService.cs#L66-L81

    public async Task<string> PostFile(string url, string filepath)
    {
        var request = new HttpClient();
        var form = new MultipartFormDataContent();
        string responseString = null;
        using (var fileStream = new FileStream(filepath, mode: FileMode.Open))
        {
            using (var bufferedStream = new BufferedStream(fileStream))
            {
                form.Add(new StreamContent(bufferedStream), "file", new FileInfo(filepath).FullName);
                var response = await request.PostAsync(url, form);
                responseString = await response.Content.ReadAsStringAsync();
                fileStream.Close();
            }
        }
        return responseString;
    }

我在该代码中找不到任何错误,它适用于小型文件。 (约500MB)

但是如果我上传一个大约2GB的大文件,则会导致异常:

  

操作被取消。将内容复制到流时出错。无法访问已处置的对象。对象名称:“ SslStream”。

我想流是在上传时被丢弃的。

我希望我的整个文件都可以成功上传到远程服务器,并且该过程不会占用我的大部分RAM。那么我的代码有什么问题呢?给我一些例子吗?

其他信息:

我查看了上游HTTP服务器的日志,并显示该连接已由远程客户端终止。并且该连接在关闭之前持续了1.7分钟。

日志显示:

  

远程主机强制关闭现有连接远程主机强制关闭现有连接

1 个答案:

答案 0 :(得分:0)

我发现了问题:HTTP客户端的默认超时为100秒。源代码在这里:

https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/System/Net/Http/HttpClient.cs#L17

我已经这样更改了我的代码:

        public async Task<string> PostFile(string url, string filepath)
        {
            var request = new HttpClient
            {
                Timeout = TimeSpan.FromSeconds(3600)
            };
            var form = new MultipartFormDataContent();
            string responseString = null;
            using (var fileStream = new FileStream(filepath, mode: FileMode.Open))
            {
                using (var bufferedStream = new BufferedStream(fileStream))
                {
                    form.Add(new StreamContent(bufferedStream), "file", new FileInfo(filepath).FullName);
                    var response = await request.PostAsync(url, form);
                    responseString = await response.Content.ReadAsStringAsync();
                    fileStream.Close();
                }
            }
            return responseString;
        }

问题解决了。