加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 发送HTTP时的OutputStream OutOfMemoryError

发布时间:2020-12-14 16:31:54 所属栏目:Java 来源:网络整理
导读:我试图将一个大的视频/图像文件从本地文件系统发布到http路径,但是在一段时间后我遇到内存不足错误… 这里是代码 public boolean publishFile(URI publishTo,String localPath) throws Exception { InputStream istream = null; OutputStream ostream = null
我试图将一个大的视频/图像文件从本地文件系统发布到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,buf.length)) > 0) {
                ostream.write(buf,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;

}

HEre是我正在收到的错误…

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头(每 HTTP spec).

一种替代方案,如果您的目标服务器支持它,则使用“chunked”传输.这将一次缓冲一小部分数据.然而,并不是所有的服务都支持它(例如,Amazon S3)不支持.

另一个选择(而且更好的一个)是使用Jakarta HttpClient.您可以在文件的请求中设置“实体”,并且连接代码将适当地设置请求头.

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

但是,我仍然建议使用Jakarta HttpClient,因为它减少了OP必须维护的代码量.代码是样板,但仍然有潜在的错误:

> OP正确处理在输入和输出之间复制的循环.通常当我看到一个例子,海报没有正确检查返回的缓冲区大小,或者不断重新分配缓冲区.恭喜,但您现在必须确保您的继任者非常小心.
>异常处理不太好.是的,OP记得在一个最后的块中关闭连接,再次恭喜你.除了close()调用可能抛出IOException之外,保持另一个不执行.而且整个方法抛出异常,所以编译器不会帮助捕获类似的错误.
>我计算31行代码来设置和执行响应(不包括响应代码检查和URL计算,但包括try / catch / finally).使用HttpClient,这将在几十个LOC的范围内.

即使OP完美地编写了这段代码,并将其重构成类似于Jakarta Commons IO的方法,他/他不应该这样做.此代码已经被其他人编写和测试.我知道这是浪费我改写的时间,并怀疑这是浪费OP的时间.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读