【问题标题】:Decompress large binary files解压大型二进制文件
【发布时间】:2020-05-19 11:51:37
【问题描述】:

我有一个使用以下方法解压缩大型 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)

【问题讨论】:

  • 您对输入和输出文件都使用s,这是行不通的。你不能写你正在阅读的同一个文件。

标签: java compression gzip binaryfiles


【解决方案1】:

不要使用Reader 类,因为您不需要逐个字符或逐行编写输出文件。您应该使用InputStream.transferTo() 方法通过byte 读写byte

try(var in = new GZIPInputStream(new FileInputStream(inFile));
    var out = new FileOutputStream(outFile)) {
    in.transferTo(out);           
}

另外,您可能不需要显式调用flush(),在每一行之后都这样做是浪费。

【讨论】:

  • 感谢您的建议。这是带有 var 的 java 8+ 语法?
  • Java 10+ 语法
  • 我正在使用的系统是在 Java 7 上的。我确实在我使用 Java 11 的个人机器上测试了这段代码
  • 你甚至不能使用transferTo,因为它是 Java 9+。看看它是如何在OpenJDK 中实现的
  • 兼容 Java 7 的替代方案并不复杂:try(GZIPInputStream in = new GZIPInputStream(new FileInputStream(inFile))) { Files.copy(in, Paths.get(outFile)); } 方法 Files.copy 自 Java 7 起就存在。在这种特定情况下,即使对于较新的版本,它也可能是首选解决方案,因为它不是需要手动处理目标OutputStream
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 2018-01-04
  • 1970-01-01
  • 1970-01-01
  • 2013-09-07
  • 1970-01-01
  • 2020-04-27
相关资源
最近更新 更多