简体   繁体   中英

How to upload a large file to another HTTP service using C#?

I am working on a project written by C# on .NET Core 2.2. In my code I need to upload a large file (about 2GB) to a remote HTTP server.

I am not responsible for the remote server. I am only reponsible for the upload logic.

What is the best practice for uploading a large local file via HTTP in C#?

I have tried the following code

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;
    }

I couldn't find any mistake in that code and it works with small files. (About 500MB)

But it caused an exception if I upload a large file about 2GB:

The operation was canceled. Error while copying content to a stream. Cannot access a disposed object. Object name: 'SslStream'.

I guess the stream was disposed while uploading.

I expect my entire file can be successfully uploaded to the remote server and the process won't eat most of my RAM. So what's wrong with my code? is there some example for me?

Additional info:

I looked at the log of the upstream HTTP server and showed that the connection was ended by the remote client. And the connection lasted 1.7 minutes before it was closed.

The log says:

An existing connection was forcibly closed by the remote host An existing connection was forcibly closed by the remote host

I found the problem: The default timeout for HTTP client is 100 seconds. Source code is here:

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

And I have changed my code like this:

        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;
        }

And the problem solved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM