[英]Can I add PushStreamContent to MultipartFormDataContent without HttpClient buffering whole request?
I am trying to send a large file in an HTTP POST, along with some other data, using a MultipartFormDataContent
. 我正在尝试使用
MultipartFormDataContent
在HTTP POST中发送一个大文件以及其他一些数据。 To send the file in chunks, I am using a PushStreamContent
which writes chunks of data from my file stream to output stream, flushing after each write: 为了分块发送文件,我使用的是
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();
});
If I POST this HttpContent
using the following code, everything works fine: 如果我使用以下代码发布此
HttpContent
,则一切正常:
new HttpClient().PostAsync(destinationUrl, pushStreamContent);
If, however, this PushStreamContent
is added to a MultipartFormDataContent
, as follows: 但是,如果将此
PushStreamContent
添加到MultipartFormDataContent
,则如下所示:
MultipartFormDataContent postForm = new MultipartFormDataContent {
{stringContent, "atom"},
{pushStreamContent, "binary"}
};
and that is posted, then I receive an OutOfMemoryException
within the lambda of the PushStreamContent
. 和被贴出来,然后我收到
OutOfMemoryException
的的拉姆达内PushStreamContent
。 Presumably, the HttpClient
is buffering the whole of the MultipartFormDataContent
into memory, which fails as the request content is very large. 据推测,
HttpClient
正在将整个 MultipartFormDataContent
缓冲到内存中,由于请求内容非常大,该操作将失败。 I would like the client to defer to the flushing of the contained PushStreamContent
. 我希望客户端
PushStreamContent
所包含的PushStreamContent
。 Is this possible? 这可能吗? I am using .NET 4.5.
我正在使用.NET 4.5。
The request is being buffered because HttpClient
needs to know the total length of the request in order to set the Content-Length header. 由于
HttpClient
需要知道请求的总长度才能设置Content-Length标头,因此正在缓冲该请求。 A PushStreamContent
object always returns false for TryComputeLength(out long)
. PushStreamContent
对象对于TryComputeLength(out long)
始终返回false 。
Thus the solution is to create a sub-class of PushStreamContent
which does know its length: 因此,解决方案是创建一个不知道其长度的
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;
}
}
If one of these is added to a MultipartFormDataContent
, the data is pushed to the stream during an HTTP post, rather than being pre-loaded into memory. 如果将其中之一添加到
MultipartFormDataContent
,则在HTTP发布期间将数据推送到流,而不是预先加载到内存中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.