HttpWebRequest 流写入永远不会完成

发布于 2024-11-13 21:55:55 字数 961 浏览 1 评论 0原文

我正在发布一个带有 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往日情怀 2024-11-20 21:55:55

已解决:关闭 HttpWebRequest 上的 AllowWriteStreamBuffering。看起来当它打开时,无论 Write() 调用写入最后一个字节,它都不会返回,直到内部缓冲区被清除。所以最后一个 Write() 最终开始竞争,直到我失去耐心。

由于我最初想做的是确定进度,因此关闭缓冲无论如何都会让事情变得更清晰。

Solved: Turned off AllowWriteStreamBuffering on the HttpWebRequest. Looks like when it's on, whatever Write() call writes the last byte, it doesn't return till the internal buffer's cleared. So the last Write() 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.

紫竹語嫣☆ 2024-11-20 21:55:55

一个常见的问题是忘记关闭请求流。您将看到的症状之一是从未提出请求。写入很可能确实已完成,但由于您没有关闭请求流,因此对 HttpWebRequest.GetResponse() 的调用似乎并未执行。

请尝试以下操作,看看是否有所不同:

using (var requestStream = myRequest.GetRequestStream())
{
    // write to the request stream here
}
// Now try to get the response.

另一个可能的问题是数据的大小。首先,您确定服务器可以处理 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:

using (var requestStream = myRequest.GetRequestStream())
{
    // write to the request stream here
}
// Now try to get the response.

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 and ReadWriteTimeout properties.

北笙凉宸 2024-11-20 21:55:55

当您构建请求时,您的内容长度也应包括标头,确保其不仅仅设置为文件长度。
您可以尝试的另一件事是在一切完成后在流上调用 .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 nice UploadFile() method you can use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文