【问题标题】:Listing of files inside 7-zip archive takes some seconds to complete7-zip 存档中的文件列表需要几秒钟才能完成
【发布时间】:2014-10-09 08:03:47
【问题描述】:

我正在尝试使用 Apache Commons Compress 读取 7-zip 文件的内容。我对阅读/提取内容不感兴趣,我只想获取所有条目的列表。

我编写了这段代码,但是对于 4MB 的存档,读取整个文件需要 6 秒。

public static void main(String[]args) throws IOException{
    File sevenz = new File("testfile.7z");
    System.out.println("Reading 7-zip...");
    SevenZFile sevenZFile = new SevenZFile(sevenz);
    long s = System.currentTimeMillis();
    SevenZArchiveEntry entry;
    while((entry=sevenZFile.getNextEntry())!=null){
        System.out.print(entry.isDirectory()?"Dir":"File");
        System.out.print("\t");
        System.out.print("*********.***"); //entry.getName();
        System.out.print("\t");
        System.out.println(entry.getHasCrc()?"CRC":"NO-CRC");
    }
    System.out.println("------------------------------");
    System.out.println("7-zip\t"+(System.currentTimeMillis()-s)+" ms to read.");

}   

输出是:

Reading 7-zip...
File    *********.***   CRC
File    *********.***   CRC
File    *********.***   CRC
File    *********.***   CRC
File    *********.***   CRC
------------------------------
7-zip   6236 ms to read.

文件列表过程是否应该花费这么长时间,还是我做错了什么? 我还尝试删除所有打印件,但读取文件所需的时间是相同的。

【问题讨论】:

    标签: java apache-commons-compress


    【解决方案1】:

    这似乎有点偏高。我会做的第一件事是消除多余的精力和时间只阅读部分。

    这意味着注释掉循环内的所有System.out.println 命令:

    while ((entry = sevenZFile.getNextEntry()) != null) {
    }
    System.out.println("total\t" + (System.currentTimeMillis()-s) + " ms.");
    

    这样做,看看它是否有所作为。这将告诉您是条目扫描本身还是打印和/或从每个条目中提取数据。

    除此之外,您还可以了解每次迭代需要多长时间:

    while ((entry = sevenZFile.getNextEntry()) != null) {
        long s2 = System.currentTimeMillis();
        System.out.println("entry\t" + (s2-s) + " ms.");
        s = s2;
    }
    

    我有一个模糊的回忆,Apache Commons Compress 在启动时读取了整个条目列表,并且根据源代码here 似乎是这种情况。

    一种可能性是获取该源代码,将其暂时按原样合并到您自己的代码中,然后对其进行分析以查看它在实例化过程中大部分时间花费在哪里。

    【讨论】:

    • 花费相同的时间。
    • 我更改了代码以查看到达每个文件需要多长时间,问题在于最大文件(未压缩 16MB)之后的getNextEntry。条目列表是在创建 SevenZFile 对象时生成的,但似乎 getNextEntry 做了一些事情来“准备”要读取的文件内容,并且没有选项可以禁用它。可能这就是问题所在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多