代码之家  ›  专栏  ›  技术社区  ›  Jakub Krampl

通过HttpClient发送大文件

  •  5
  • Jakub Krampl  · 技术社区  · 7 年前

    我需要通过HTTP协议上传大文件(约200MB)。我希望避免将文件加载到内存中,并希望直接发送它们。

    多亏了这个 article 我能做到 HttpWebRequest .

    HttpWebRequest requestToServer = (HttpWebRequest)WebRequest.Create("....");
    
    requestToServer.AllowWriteStreamBuffering = false;
    requestToServer.Method = WebRequestMethods.Http.Post;
    requestToServer.ContentType = "multipart/form-data; boundary=" + boundaryString;
    requestToServer.KeepAlive = false;
    requestToServer.ContentLength = ......;
    
    using (Stream stream = requestToServer.GetRequestStream())
    {
        // write boundary string, Content-Disposition etc.
        // copy file to stream
        using (var fileStream = new FileStream("...", FileMode.Open, FileAccess.Read))
        {
            fileStream.CopyTo(stream);
        }
    
        // add some other file(s)
    }
    

    但是,我想通过 HttpClient . 我发现 article 其中描述了 HttpCompletionOption.ResponseHeadersRead 我尝试过这样的方法,但不幸的是,它不起作用。

    WebRequestHandler handler = new WebRequestHandler();
    
    using (var httpClient = new HttpClient(handler))
    {
        httpClient.DefaultRequestHeaders.Add("ContentType", "multipart/form-data; boundary=" + boundaryString);
        httpClient.DefaultRequestHeaders.Add("Connection", "close");
    
        var httpRequest = new HttpRequestMessage(HttpMethod.Post, "....");
    
        using (HttpResponseMessage responseMessage = await httpClient.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead))
        {
            using (Stream stream = await responseMessage.Content.ReadAsStreamAsync())
            {
                // here I wanted to write content to the stream, but the stream is available only for reading
            }
        }
    }
    

    也许我忽略或错过了什么。。。


    更新

    除此之外,使用 StreamContent 具有适当的标题:

    1 回复  |  直到 7 年前
        1
  •  5
  •   Cory Nelson    7 年前

    请参见 StreamContent 类别:

    HttpResponseMessage response =
        await httpClient.PostAsync("http://....", new StreamContent(streamToSend));
    

    在您的示例中,您得到 回答 并尝试写入它。相反,您必须为 要求 ,如上所述。

    这个 HttpCompletionOption.ResponseHeadersRead 是禁用响应流的缓冲,但不影响请求。如果您的响应很大,通常会使用它。

    要发布多个表单数据文件,请使用 MultipartFormDataContent :

    var content = new MultipartFormDataContent();
    
    content.Add(new StreamContent(stream1), "file1.jpg");
    content.Add(new StreamContent(stream2), "file2.jpg");
    
    HttpResponseMessage response =
        await httpClient.PostAsync("http://...", content);