【问题标题】:OutOfMemory on big HTTP MultipartRequestEntity via apache HttpClient 3.1通过 apache HttpClient 3.1 在大型 HTTP MultipartRequestEntity 上的 OutOfMemory
【发布时间】:2018-12-05 11:13:24
【问题描述】:

我实际上是在尝试在低内存环境中通过 MultipartRequestEntity 和 java 1.4 使用 apache HttpClient 3.1 上传文件 (>5M),因此无法增加 java 堆

我有一个文件拆分成很多部分,我只需要将每个部分的所有数据附加到请求中,我也可以不拆分得到文件

真正的问题是我正在构建的请求正在产生内存溢出,有没有办法避免这种情况并能够立即发送这个请求?

这是我实际拥有的,我需要将字节附加到部分(一种 part[0].write(data)),或者获取一个流来写入它而不加载到内存中,我不不知道有没有可能

    HttpClient client = new HttpClient();
    PostMethod post = new PostMethod(url);

    post.setContentChunked(true);

    try {
        Part[] parts = new Part[fileNames.size()];

        String fileName = "sample.pdf";

        for(int i = 0; i<fileNames.size();i++){
            File file = Util.getFile(fileNames.get(i));
            FileInputStream is = new FileInputStream(file);
            byte[] fileBytes = IOUtils.toByteArray(is);
            parts[i] = new FilePart("file", new ByteArrayPartSource(fileName, fileBytes) , "application/octet-stream", post.getRequestCharSet()); 
            is.close();
            is = null;
            fileBytes = null;
        }

     MultipartRequestEntity requestEntity = new MultipartRequestEntity(parts, post.getParams());

     post.setRequestEntity(requestEntity);


     int statusCode = client.executeMethod(post);

另一种可能性是 HttpUrlConnection 写入一个 BufferedWriter,但这也会在写入时产生 OutOfMemory

【问题讨论】:

  • HTTP 性能客户端网站值得一读...hc.apache.org/httpclient-3.x/performance.html
  • 您能说得更具体些吗?我已经检查了它的网站,也许我没有正确解释自己,我会编辑我的答案以免混淆
  • 诀窍是不要在内存中建立整个请求。我不知道您是否可以使用 Apache 客户端(从未使用过)来做到这一点,但您当然可以使用原始 HttpConnection 来做到这一点。
  • 我在 HttpConnection 中看到了一个名为 setFixedLengthStreamingMode 的方法,我想这就是您所说的,但它是为 java 1.5 及更高版本指定的
  • 您构建自己的请求实体。

标签: java http out-of-memory httpclient multipart


【解决方案1】:

我可以直接使用 File java 文件类来完成此操作,但问题是我没有 java File 类,而是我必须实现 PartSource 来读取我的特殊文件类并在加入我的所有文件后将其设置为读取强制将部分文件放在一个文件中。 通常你应该这样做:

parts[0] = new FilePart("file", new FilePartSource(file) , "application/octet-stream", postMethod.getRequestCharSet()); 

如果您不想为请求将整个数据缓冲在内存中,则需要一个文件

现在我解决了这个问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    相关资源
    最近更新 更多