解压缩大型二进制文件
Decompress large binary files
我有使用以下方法解压缩大型 zip 文件的功能。他们是我 运行 进入 OutOfMemoryError
错误的时候,因为文件太大了。有什么方法可以优化我的代码吗?我已经阅读了一些关于将文件分成可以放入内存并解压缩的较小部分的内容,但我不知道该怎么做。如有任何帮助或建议,我们将不胜感激。
private static String decompress(String s){
String pathOfFile = null;
try(BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(s)), Charset.defaultCharset()))){
File file = new File(s);
FileOutputStream fos = new FileOutputStream(file);
String line;
while((line = reader.readLine()) != null){
fos.write(line.getBytes());
fos.flush();
}
pathOfFile = file.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
return pathOfFile;
}
堆栈跟踪:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.Arrays.copyOf(Arrays.java:3689)
at java.base/java.util.ArrayList.grow(ArrayList.java:237)
at java.base/java.util.ArrayList.ensureCapacity(ArrayList.java:217)
不要使用Reader
类,因为您不需要逐字符或逐行写入输出文件。您应该通过 byte
使用 InputStream.transferTo()
方法读写 byte
:
try(var in = new GZIPInputStream(new FileInputStream(inFile));
var out = new FileOutputStream(outFile)) {
in.transferTo(out);
}
此外,您可能不需要显式调用 flush()
,在每一行之后都调用它是一种浪费。
我有使用以下方法解压缩大型 zip 文件的功能。他们是我 运行 进入 OutOfMemoryError
错误的时候,因为文件太大了。有什么方法可以优化我的代码吗?我已经阅读了一些关于将文件分成可以放入内存并解压缩的较小部分的内容,但我不知道该怎么做。如有任何帮助或建议,我们将不胜感激。
private static String decompress(String s){
String pathOfFile = null;
try(BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(s)), Charset.defaultCharset()))){
File file = new File(s);
FileOutputStream fos = new FileOutputStream(file);
String line;
while((line = reader.readLine()) != null){
fos.write(line.getBytes());
fos.flush();
}
pathOfFile = file.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
return pathOfFile;
}
堆栈跟踪:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.Arrays.copyOf(Arrays.java:3689)
at java.base/java.util.ArrayList.grow(ArrayList.java:237)
at java.base/java.util.ArrayList.ensureCapacity(ArrayList.java:217)
不要使用Reader
类,因为您不需要逐字符或逐行写入输出文件。您应该通过 byte
使用 InputStream.transferTo()
方法读写 byte
:
try(var in = new GZIPInputStream(new FileInputStream(inFile));
var out = new FileOutputStream(outFile)) {
in.transferTo(out);
}
此外,您可能不需要显式调用 flush()
,在每一行之后都调用它是一种浪费。