HttpWebRequest 流写入永远不会完成
我正在发布一个带有 HttpWebRequest
的文件,以及页眉和页脚。标头(约 0.5K)和实际文件似乎写得很好,但对于大文件(约 15MB),页脚(大约 29 字节)似乎永远不会写。
using (Stream requestStream = request.GetRequestStream()) {
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
byte[] buffer = new byte[Math.Min(4096L, fileSize)];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) {
requestStream.Write(buffer, 0, bytesRead);
}
// next line never completes
requestStream.Write(postFooterBytes, 0, postFooterBytes.Length);
// code below is never reached
Console.WriteLine("Why do I never see this message in the console?");
}
有什么想法吗?
ETA:尝试在最后一个Write()
之前刷新流,希望有帮助,但没有效果。
再次编辑:添加了using()
以澄清我不是一个完全白痴。另请注意,这是在 fileStream
的另一个 using()
块内。
I'm posting a file with HttpWebRequest
, along with a header and footer. The header (ca. 0.5K) and the actual file seem to write fine, but with large files (ca. 15MB), the footer (which is like 29 bytes) never seems to write.
using (Stream requestStream = request.GetRequestStream()) {
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
byte[] buffer = new byte[Math.Min(4096L, fileSize)];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) {
requestStream.Write(buffer, 0, bytesRead);
}
// next line never completes
requestStream.Write(postFooterBytes, 0, postFooterBytes.Length);
// code below is never reached
Console.WriteLine("Why do I never see this message in the console?");
}
Any thoughts?
ETA: Tried flushing the stream before the last Write()
, on the off chance it would help, but to no effect.
Edited again: Added using()
to clarify that I'm not a complete idiot. Note also BTW that this is inside another using()
block for fileStream
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
已解决:关闭
HttpWebRequest
上的AllowWriteStreamBuffering
。看起来当它打开时,无论Write()
调用写入最后一个字节,它都不会返回,直到内部缓冲区被清除。所以最后一个Write()
最终开始竞争,直到我失去耐心。由于我最初想做的是确定进度,因此关闭缓冲无论如何都会让事情变得更清晰。
Solved: Turned off
AllowWriteStreamBuffering
on theHttpWebRequest
. Looks like when it's on, whateverWrite()
call writes the last byte, it doesn't return till the internal buffer's cleared. So the lastWrite()
was eventually competing, just not till I ran out of patience.And since what I was originally trying to do was determine progress, turning off buffering makes things clearer anyway.
一个常见的问题是忘记关闭请求流。您将看到的症状之一是从未提出请求。写入很可能确实已完成,但由于您没有关闭请求流,因此对
HttpWebRequest.GetResponse()
的调用似乎并未执行。请尝试以下操作,看看是否有所不同:
另一个可能的问题是数据的大小。首先,您确定服务器可以处理 15 MB 的上传吗?其次,如果您在慢速连接上执行此操作,则 15 MB 可能需要一段时间才能发送。我拥有 1.5 兆位/秒的“快速”上游连接。最好的情况是每秒 0.15 兆字节。发送 15 兆字节将需要一分半钟以上。
另一种可能性是请求超时。您想要查看 HttpWebRequest.Timeout 和 ReadWriteTimeout 属性。
A common problem is forgetting closing the request stream. One of the symptoms you'll see is that the request is never made. It's quite likely that the write really is completing, but since you didn't close the request stream, the call to
HttpWebRequest.GetResponse()
appears not to be executed.Try the following and see if it makes a difference:
Another possible issue is the size of the data. First, are you sure that the server can handle a 15 MB upload? Secondly, if you're doing this on a slow connection, 15 MB can take a while to send. I have what's considered a "fast" upstream connection at 1.5 megabits/sec. That's, at best, 0.15 megabytes per second. Sending 15 megabytes will take over a minute and a half.
One other possibility is that the request is timing out. You want to look into the
HttpWebRequest.Timeout
andReadWriteTimeout
properties.当您构建请求时,您的内容长度也应包括标头,确保其不仅仅设置为文件长度。
您可以尝试的另一件事是在一切完成后在流上调用
.Flush()
。我不确定吉姆建议的关闭 HttpClient 流的含义,它可能有效,也可能会使情况变得更糟。
使用
System.Net.WebClient
是否无法为您提供足够的灵活性?您可以使用一个很好的UploadFile()
方法。When you are building your request, your content length should include the headers as well, make sure its not just set to the file length.
The other thing you may try is to call
.Flush()
on the stream when all is said and done.I'm not sure of the implication of closing the stream for the HttpClient as Jim suggests, it may work, it may make it worse.
Does using
System.Net.WebClient
not offer enough flexibility for you? Theres a niceUploadFile()
method you can use.