简体   繁体   English

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

[英]writing a huge file and Java heap space

I am trying to write a huge file, between 500mb to 1.5 gb , into the disk. 我正在尝试在磁盘中写入500mb至1.5 gb之间的巨大文件。 i used zipOutputStream to zip it then send it over the network 我用zipOutputStream压缩它,然后通过网络发送

but in client, when im trying to unzip and write it, it gives me Java heap space. 但是在客户端中,当我尝试解压缩并编写它时,它给了我Java heap space. exception 例外

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

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

i know thats quite big memory allocation for an array of bytes, but how possibly i can fix it? 我知道那是一个字节数组相当大的内存分配,但是我怎么可能解决呢?

the byte[] array you are making is your buffer, the buffer serves as the temporary location in the heap while in transit from your InputStream to your OutputStream . 您正在创建的byte[]数组是您的缓冲区,当从InputStreamOutputStream传输时,缓冲区用作堆中的临时位置。 Unless you want your program to use 500mb - 1.5gb in memory you need to reduce your buffer size. 除非您希望程序在内存中使用500mb-1.5gb,否则需要减小缓冲区大小。 Here is a common method I use for doing this operation. 这是我执行此操作的常用方法。 This method uses a 1kb buffer, you can play with the size and see what suits you best. 此方法使用一个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();
}

Your code using this method would look something like 使用此方法的代码看起来像

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

Instead of reading the entire file into memory all at once, you can accomplish the same thing with Files.copy(zips, outFile.toPath()); 您可以使用Files.copy(zips, outFile.toPath());完成相同的操作,而不必一次将整个文件都读入内存Files.copy(zips, outFile.toPath()); . Documentation for the Files.copy method is here . 这里是Files.copy方法的文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM