我正在尝试将 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);
}
我知道对于一个字节数组来说这是一个非常大的内存分配,但我怎么能修复它呢?
答案 0 :(得分:4)
您正在制作的byte[]
数组是您的缓冲区,缓冲区在从InputStream
到OutputStream
的传输过程中充当堆中的临时位置。除非您希望程序在内存中使用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。