【问题标题】:Can I add PushStreamContent to MultipartFormDataContent without HttpClient buffering whole request?我可以在没有 HttpClient 缓冲整个请求的情况下将 PushStreamContent 添加到 MultipartFormDataContent 吗?
【发布时间】:2016-09-02 10:37:05
【问题描述】:

我正在尝试使用MultipartFormDataContent 在 HTTP POST 中发送一个大文件以及一些其他数据。为了分块发送文件,我使用PushStreamContent 将文件流中的数据块写入输出流,每次写入后刷新:

PushStreamContent pushStreamContent = new PushStreamContent((stream, content, context) => {
    byte[] buffer = new byte[4096];
    int bytesRead;
    do {
        bytesRead = fileStream.Read(buffer, 0, 4096);
        stream.Write(buffer, 0, bytesRead);
        stream.Flush();
    }
    while(bytesRead != 0);
    stream.Close();
});

如果我使用以下代码发布此HttpContent,一切正常:

new HttpClient().PostAsync(destinationUrl, pushStreamContent);

但是,如果将此PushStreamContent 添加到MultipartFormDataContent,如下所示:

MultipartFormDataContent postForm = new MultipartFormDataContent {
    {stringContent, "atom"},
    {pushStreamContent, "binary"}
};

并且 已发布,然后我在 PushStreamContent 的 lambda 中收到 OutOfMemoryException。据推测,HttpClient 正在将MultipartFormDataContent整个 缓冲到内存中,由于请求内容非常大而失败。我希望客户推迟对包含的PushStreamContent 的刷新。这可能吗?我正在使用 .NET 4.5。

【问题讨论】:

    标签: c# .net post multipartform-data dotnet-httpclient


    【解决方案1】:

    请求正在缓冲,因为HttpClient 需要知道请求的总长度才能设置 Content-Length 标头。一个PushStreamContent 对象always returns false 代表TryComputeLength(out long)

    因此解决方案是创建一个PushStreamContent 的子类,确实知道它的长度:

    class PushStreamContentWithLength : PushStreamContent {
        public PushStreamContentWithLength(Action<Stream, HttpContent, TransportContext> onStreamAvailable, long streamLength) : base(onStreamAvailable) {
            mStreamLength = streamLength;
        }
    
        readonly long mStreamLength;
    
        protected override bool TryComputeLength(out long length) {
            length = mStreamLength;
            return true;
        }
    }
    

    如果将其中之一添加到MultipartFormDataContent,则数据会在 HTTP 发布期间推送到流中,而不是预加载到内存中。

    【讨论】:

      猜你喜欢
      • 2013-03-16
      • 2022-12-16
      • 1970-01-01
      • 1970-01-01
      • 2016-04-14
      • 1970-01-01
      • 2012-08-23
      • 2021-12-27
      • 2014-03-01
      相关资源
      最近更新 更多