Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编写巨大的文件和Java堆空间_Java_File_Exception_Client Server - Fatal编程技术网

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

编写巨大的文件和Java堆空间,java,file,exception,client-server,Java,File,Exception,Client Server,我正试图将一个500mb到1.5GB之间的大文件写入磁盘。 我使用zipOutputStream将其压缩,然后通过网络发送 但在客户端,当我试图解压和 写它,它给我Java堆空间。exception try (FileOutputStream fos = new FileOutputStream(outFile)) { int fileLength = (int)zipEntry.getSize(); byte[] fileB

我正试图将一个500mb到1.5GB之间的大文件写入磁盘。 我使用
zipOutputStream
将其压缩,然后通过网络发送

但在客户端,当我试图解压和 写它,它给我
Java堆空间。
exception

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

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

我知道一个字节数组的内存分配相当大,但我怎么可能修复它呢?

您正在制作的
字节[]
数组是您的缓冲区,在从
输入流
传输到
输出流时,缓冲区充当堆中的临时位置。除非您希望程序在内存中使用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);
}

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

您可以一次读取/写入部分文件。这就是流的设计用途。你一次读/写8K怎么样?@PeterLawrey如何分配流的大小?你也可以用
文件来完成同样的事情。copy(zips,outFile.toPath())。看到了吗?@VGR想把它变成一个答案吗?wekk用了将近2分钟的时间来传输文件,我被困在了如何使它只读取几个KB的部分中,而你给我看了。谢天谢地,我想知道缓冲区大小,例如10KB,是否意味着spead是10X?哦,我的打字错误,我的意思是速度我知道答案是不,但是,在这种情况下,我们定义一个缓冲区,使用最大可能空间来缓冲,而不是小的1KB缓冲区怎么样?@lonesome最有可能的瓶颈是你的下载速度。只有当您看到高CPU利用率(忽略系统时间)时,它才表明更大的缓冲区可能会有所帮助。顺便说一句,您自己尝试这样做并没有坏处。试试4KB、16KB、64KB等等,看看你是否认为这会有所不同。那么,你认为哪种方式更好?缓冲还是这个复制方法?
文件。copy
更好,因为使用它可读性更好,而且我相信它目前有自己的缓冲,所以肯定不会比自己做的更糟。我使用文件时堆空间仍然不足。copy。。。有没有办法用这个来指定缓冲区大小?@Rimer我需要看看你的代码。除非您试图将整个文件读入ByteArrayOutputStream或其他文件,否则不可能耗尽空间。我知道我已经使用files.copy复制了3 GB文件,没有任何问题。我的错误我在堆空间不足时运行了错误的代码分支。文件复制成功了!它使用一个8KB的缓冲区,顺便说一句,我从源代码窥探中发现。。。