通过 apache HttpClient 3.1 在大型 HTTP MultipartRequestEntity 上出现 OutOfMemory

OutOfMemory on big HTTP MultipartRequestEntity via apache HttpClient 3.1

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

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

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

这就是我实际拥有的,我需要将字节附加到部分(一种部分[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

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

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

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

现在我已经解决了这个问题