编写一个巨大的文件和Java堆空间

时间:2014-06-15 07:48:23

标签: java file exception client-server

我正在尝试将 500mb到1.5 gb 之间的大文件写入磁盘。 我使用zipOutputStream压缩它然后通过网络发送

但在客户端,当我试图解压缩和 写它,它给了我Java heap space.例外

  try (FileOutputStream fos = new FileOutputStream(outFile)) {
                int fileLength = (int)zipEntry.getSize();

                byte[] fileByte = new byte[fileLength];
                zips.read(fileByte);
                fos.write(fileByte);
            }

我知道对于一个字节数组来说这是一个非常大的内存分配,但我怎么能修复它呢?

2 个答案:

答案 0 :(得分:4)

您正在制作的byte[]数组是您的缓冲区,缓冲区在从InputStreamOutputStream的传输过程中充当堆中的临时位置。除非您希望程序在内存中使用500mb - 1.5gb,否则需要减小缓冲区大小。这是我用于执行此操作的常用方法。这个方法使用1kb缓冲区,你可以玩大小,看看最适合你的。

/**
 * writes all bytes from inputStream to outputStream
 * @param source
 * @param destination
 * @throws IOException
 */
public static void pipeStreams(java.io.InputStream source, java.io.OutputStream destination) throws IOException {

    // 1kb buffer
    byte [] buffer = new byte[1024];
    int read = 0;
    while((read=source.read(buffer)) != -1) {
        destination.write(buffer, 0, read);
    }
    destination.flush();
}

使用此方法的代码看起来像

try (FileOutputStream fos = new FileOutputStream(outFile)) {
    pipeStreams(zips, fos);
}

答案 1 :(得分:2)

您可以使用Files.copy(zips, outFile.toPath());完成相同的操作,而不是一次性将整个文件读入内存。 Files.copy方法的文档是here