尽管设置了分块流模式,但 HttpURLConnection 缓冲而不是流?
我正在使用 HttpURLConnection 向服务器写入文件,其中一些文件非常大。
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
不久前,我在写入 1 GB 或更大的对象时遇到了问题。我通过将其设置为流式传输更易于管理的块大小来修复此问题。
final int bufferSize = 1024 * 1024;
[...]
conn.setChunkedStreamingMode(bufferSize);
然后它在我的笔记本电脑上运行良好,但在其他机器上却崩溃了。经过调查,我发现原因是写入输出流时发生内存不足错误。
final OutputStream out = conn.getOutputStream();
final long bytesWritten = IOUtils.copyLarge(in, out);
在 copyLarge 例程中,我发现它能够执行 4096 字节的 262145 次迭代,但在尝试跨越 1 GB 线时失败。为 java 应用程序分配更多内存似乎可以防止这些崩溃,但我认为这应该是不必要的。如果它正在写入 1 MB 的块,那么它要么会因迭代次数少得多而失败,要么重复写入 1 MB 而不会出现问题。
更新:事实证明,设置 ChunkedStreamingMode 的行实际上并未在某些机器上被调用。如果您没有设置固定/分块流模式,HttpURLConnection 只会将所有内容发送到 PosterOutputStream/ByteArrayOutputStream。
I am using HttpURLConnection
to write files, some of which are quite large, to a server.
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
A while back I had issues writing objects 1 GB or more. I fixed that by setting it to stream a more manageable chunk size.
final int bufferSize = 1024 * 1024;
[...]
conn.setChunkedStreamingMode(bufferSize);
It had then been running fine on my laptop, but on other machines it was crashing. On investigation, I found that the cause was an out of memory error that occurred when writing to the output stream.
final OutputStream out = conn.getOutputStream();
final long bytesWritten = IOUtils.copyLarge(in, out);
Inside the copyLarge routine I found that that it was able to do 262145 iterations of 4096 bytes, failing when it tried to cross the 1 GB line. Allocating more memory to the java application seemed to prevent those crashes, but I thought that should be unnecessary. If it is writing chunks of 1 MB, then either it should fail with far fewer iterations or repeatedly write 1 MB without issue.
UPDATE: Turns out the line setting the ChunkedStreamingMode wasn't actually being called on some machines. If you don't set fixed/chunked streaming mode, HttpURLConnection will just send everything to a PosterOutputStream/ByteArrayOutputStream.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论