【问题标题】:Count the number of files inside an entry of jar file计算jar文件条目中的文件数
【发布时间】:2021-07-30 01:40:57
【问题描述】:

我正在寻找一种方法来计算 jar 文件条目中的文件数。

例如,假设我在 jar 中有一个名为“myFolder”的文件夹,我希望能够计算其中的文件数。

我使用 here 的想法访问了 myFolder,但我不知道如何访问其中的文件。

这是我的代码:

private int countFiles() {
    JarFile jf = null;
    int counter = 0;
    try {
        jf = new JarFile(new File(ClassName.class
                .getProtectionDomain().getCodeSource().getLocation().toURI()));
        Enumeration<JarEntry> entries = jf.entries();
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            if (entry.isDirectory()) {
                if (entry.getName().equals("myFolder/")) {
                    ///////
                }
            }
        }
    } catch (Exception ex) {
        try {
            jf.close();
        } catch (Exception e) {
        }
    }
    return counter;
}

感谢您的帮助!

【问题讨论】:

  • I use this 当我想跨目录搜索并进入 jar 时。 “文件”将位于代码的 else 块(未写入)中。
  • 必须是 Java 吗?我的意思是,你可以在 shell 中jar tf | wc -l

标签: java jar


【解决方案1】:

如果您想在 Java 中执行此操作,那么使用 NIO2 API 中的 ZIP 文件系统提供程序 可能会更容易。

import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;

public class Main {

  public static void main(String[] args) throws IOException {
    Path jarFile = Path.of("path", "to", "file.jar");
    String directoryPath = "/myFolder";

    long fileCount = countFilesInDir(jarFile, directoryPath);
    System.out.println(fileCount);
  }

  public static long countFilesInDir(Path jarFile, String directory) throws IOException {
    try (FileSystem fs = FileSystems.newFileSystem(jarFile)) {
      return Files.list(fs.getPath(directory)).count();
    }
  }
}

如果您只想统计常规文件,请更改:

return Files.list(fs.getPath(directory)).count();

收件人:

return Files.list(directory).filter(Files::isRegularFile).count();

如果您想递归地计算条目/文件,请查看java.nio.file.Files#find(Path,int,BiPredicate,FileVisitOption...) 方法。


注意:通常你应该关闭由Files.listFiles.find返回的Stream,但在这种情况下,它应该作为FileSystem的结果而关闭正在关闭。

【讨论】:

    【解决方案2】:

    只有 jar 中的空目录才能通过 isDirectory 测试。
    对于文件条目,目录将包含在名称中

    shell> import java.util.jar.JarFile;
    
    JarFile jf = new JarFile(new File("test.jar"));
    jf ==> java.util.jar.JarFile@32d992b2
    
    jf.stream().forEach(f -> System.out.println(f.getName()))
    META-INF/
    META-INF/MANIFEST.MF
    dir1/Order.MOVED
    dir1/Pet.MOVED
    dir1/Tag.MOVED
    dir1/User.MOVED
    empty/
    
    jf.stream().forEach(f -> { if(f.getName().contains("dir1/")) System.out.println(f.getName()) ;})
    dir1/Order.MOVED
    dir1/Pet.MOVED
    dir1/Tag.MOVED
    dir1/User.MOVED
    jf.stream().forEach(f -> { if(f.getName().contains("dir1/dir2/")) System.out.println(f.getName()) ;})
    dir1/dir2/
    dir1/dir2/Pet.MOVED
    dir1/dir2/Order.MOVED
    

    可以不检查是否是目录就可以使用

    while (entries.hasMoreElements()) {
        JarEntry entry = entries.nextElement();
        if (entry.getName().contains("myFolder/")) {
            ///////
        }
    }
    

    这也应该有效

    while (entries.hasMoreElements()) {
        JarEntry entry = entries.nextElement();
        if (!entry.isDirectory() && entry.getName().startsWith("myFolder/")) {
            ///////
        }
    }
    

    【讨论】:

    • 对不起,我是新手,但我该如何使用它?我对java很陌生。
    • np :-) 添加了如何回答。
    • 我应该把第一个代码块放在哪里?我把它放在'if'中,但它可能不是正确的地方,因为我遇到了错误。再次感谢:)
    • 使用while... 块之一
    猜你喜欢
    • 2013-09-16
    • 2020-05-30
    • 1970-01-01
    • 2020-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多