HttpClient在发送大文件/内容时是否有缺陷

本文关键字:是否 有缺陷 文件 HttpClient | 更新日期: 2023-09-27 18:34:57

在阅读/谷歌搜索有关HttpClient之后,我的印象是该组件不适合将大文件或内容上传到REST服务。

  1. 似乎如果上传花费的时间超过既定的超时,传输将失败。有意义吗?此超时意味着什么?

  2. 获取进度信息似乎很困难或需要附加组件。

所以我的问题是:是否有可能毫不费力地解决这两个问题?否则,在处理大型内容和 REST 服务时,最佳方法是什么?

HttpClient在发送大文件/内容时是否有缺陷

  1. 是的,如果上传时间超过超时时间,则上传将失败。这是HttpClient的限制。这个问题最有力的解决方案是托马斯·莱维斯克(Thomas Levesque(写了一篇文章,并在评论中链接到您的问题。你必须使用HttpWebRequest而不是HttpClient
  2. 如果要获取进度消息,请以FileStream打开文件并手动循环访问它,以增量方式将字节复制到(上传(请求流中。在此过程中,您可以计算相对于文件大小的进度。

TL 的代码示例。不过,请务必阅读这篇文章!

long UploadFile(string path, string url, string contentType)
{
    // Build request
    var request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = WebRequestMethods.Http.Post;
    request.AllowWriteStreamBuffering = false;
    request.ContentType = contentType;
    string fileName = Path.GetFileName(path);
    request.Headers["Content-Disposition"] = string.Format("attachment; filename='"{0}'"", fileName);
    try
    {
        // Open source file
        using (var fileStream = File.OpenRead(path))
        {
            // Set content length based on source file length
            request.ContentLength = fileStream.Length;
            // Get the request stream with the default timeout
            using (var requestStream = request.GetRequestStreamWithTimeout())
            {
                // Upload the file with no timeout
                fileStream.CopyTo(requestStream);
            }
        }
        // Get response with the default timeout, and parse the response body
        using (var response = request.GetResponseWithTimeout())
        using (var responseStream = response.GetResponseStream())
        using (var reader = new StreamReader(responseStream))
        {
            string json = reader.ReadToEnd();
            var j = JObject.Parse(json);
            return j.Value<long>("Id");
        }
    }
    catch (WebException ex)
    {
        if (ex.Status == WebExceptionStatus.Timeout)
        {
            LogError(ex, "Timeout while uploading '{0}'", fileName);
        }
        else
        {
            LogError(ex, "Error while uploading '{0}'", fileName);
        }
        throw;
    }
}