gpt4 book ai didi

java - 发送 HTTP 时的 OutputStream OutOfMemoryError

转载 作者:搜寻专家 更新时间:2023-10-30 19:53:54 28 4
gpt4 key购买 nike

我正尝试从本地文件系统将一个大的视频/图像文件发布到一个 http 路径,但是一段时间后我遇到了内存不足的错误...

这是代码

public boolean publishFile(URI publishTo, String localPath) throws Exception {
InputStream istream = null;
OutputStream ostream = null;
boolean isPublishSuccess = false;

URL url = makeURL(publishTo.getHost(), this.port, publishTo.getPath());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();


if (conn != null) {

try {

conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("PUT");
istream = new FileInputStream(localPath);
ostream = conn.getOutputStream();

int n;
byte[] buf = new byte[4096];
while ((n = istream.read(buf, 0, buf.length)) > 0) {
ostream.write(buf, 0, n); //<--- ERROR happens on this line.......???
}

int rc = conn.getResponseCode();

if (rc == 201) {
isPublishSuccess = true;
}

} catch (Exception ex) {
log.error(ex);
} finally {
if (ostream != null) {
ostream.close();
}

if (istream != null) {
istream.close();
}
}
}

return isPublishSuccess;

}

这是我遇到的错误...

Exception in thread "Thread-8773" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at sun.net.www.http.PosterOutputStream.write(PosterOutputStream.java:61)
at com.test.HTTPClient.publishFile(HTTPClient.java:110)
at com.test.HttpFileTransport.put(HttpFileTransport.java:97)

最佳答案

HttpUrlConnection 正在缓冲数据,以便它可以设置 Content-Length header (根据 HTTP spec )。

如果您的目标服务器支持,另一种选择是使用“chunked”传输。这将一次只缓冲一小部分数据。但是,并非所有服务都支持它(例如,Amazon S3 不支持)。

另一种选择(在我看来是更好的选择)是使用 Jakarta HttpClient .您可以在来自文件的请求中设置“实体”,连接代码将适本地设置请求 header 。


编辑:nos 评论说 OP 可以调用 HttpURLConnection.setFixedLengthStreamingMode(long length)。我不知道这种方法;它是在 1.5 中添加的,从那时起我就没有使用过这个类。

但是,我仍然建议使用 Jakarta HttpClient,原因很简单,因为它减少了 OP 必须维护的代码量。样板代码,但仍有可能出错:

  • OP 正确处理循环以在输入和输出之间进行复制。通常当我看到这样的例子时,发布者要么没有正确检查返回的缓冲区大小,要么不断重新分配缓冲区。恭喜,但您现在必须确保您的继任者尽可能谨慎。
  • 异常处理不是很好。是的,OP 记得在 finally block 中关闭连接,再次恭喜。除了其中一个 close() 调用可能抛出 IOException,从而阻止另一个执行。该方法作为一个整体抛出 Exception,因此编译器不会帮助捕获类似的错误。
  • 我数了 31 行代码来设置和执行响应(不包括响应代码检查和 URL 计算,但包括 try/catch/finally)。使用 HttpClient,这将在六个 LOC 范围内。

即使 OP 完美地编写了这段代码,并将其重构为类似于 Jakarta Commons IO 中的方法,他/她也不应该那样做。此代码已由其他人编写和测试。我知道重写它是在浪费的时间,并且怀疑这也是在浪费 OP 的时间。

关于java - 发送 HTTP 时的 OutputStream OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2082057/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com