【问题标题】:Java - Reading files inside jarJava - 读取 jar 中的文件
【发布时间】:2016-09-10 17:14:48
【问题描述】:

我知道有很多方法可以做到这一点,但是我在这个任务中遇到了我已经找到的解决方案无法解决的问题。

首先,我不想读取 jar 中的特定文件:我想读取 all 目录中包含的文件 inside 给定 jar目录的路径。 也就是说,通过一些研究,我发现了如何做到这一点,并编写了一个测试代码。

public class StringLocalizer {

    private final List<URL> files;

    public StringLocalizer(final String stringsDirectory) throws URISyntaxException, IOException {

        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        final BufferedReader br = new BufferedReader(new InputStreamReader(loader.getResourceAsStream(stringsDirectory), StandardCharsets.UTF_8));
        files = br.lines()
                .map(l -> stringsDirectory + "/" + l)
                .map(loader::getResource)
                .collect(Collectors.toList());

        // This line has the debug purpose of showing all the url contained in the list
        System.out.println(Arrays.toString(files.toArray(new URL[files.size()]))); 
    }

    public static void main(String[] args) {

        try {
            new StringLocalizer("test/testDirectory/");
        } catch (URISyntaxException | IOException e) {
            e.printStackTrace();
        }
    }

}

首先我在我的 IDE (Eclipse) 中尝试了代码,我得到了这个输出:

[file:/C:/Users/*my_user_name*/neon/workspace/JavaStringLocalizer/bin/test/testDirectory//test.xml]

代码运行良好,这是我的第一个想法,但是当我尝试将程序打包到一个可运行的 JAR 文件中时,我得到了一个意外的输出:

[]

为什么即使文件打包成JAR文件列表也是空的?

(正确的输出应该是包含给定目录中所有文件的数组的表示形式,如第一个输出)

编辑: 为了更好地了解我的情况,我有这些文件:

>MyJar.jar
    >classFiles
    >test>testDirectory>test.xml // I want to get this file

注意:此目录将包含更多文件,因此我不想静态访问它们但我想动态读取所有文件

编辑: 使用ZipFile提取文件的代码:

public class StringLocalizer {

    private final List<ZipEntry> files = new ArrayList<ZipEntry>();

    public StringLocalizer(final String stringsDirectory) throws URISyntaxException, IOException {

        URL jarUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
        File jarFile = new File(jarUrl.toURI().getPath());

        ZipFile unzipper = new ZipFile(jarFile, ZipFile.OPEN_READ);

        ZipEntry dirEntry = unzipper.getEntry(stringsDirectory);

        Enumeration<? extends ZipEntry> entries = unzipper.entries();

        for(ZipEntry entry = entries.nextElement(); entries.hasMoreElements(); entry = entries.nextElement()) {

            if(entry.getName().startsWith(dirEntry.getName()) && !entry.getName().equals(dirEntry.getName())) {
                files.add(entry);
            }
            System.out.println(entry.getName());
        }

        System.out.println(Arrays.toString(files.toArray(new ZipEntry[files.size()])));

        unzipper.close();
    }

    public static void main(String[] args) {

        try {
            new StringLocalizer("test/testDirectory/");
        } catch (URISyntaxException | IOException e) {
            e.printStackTrace();
        }
    }

}

为什么最后一个条目被忽略了?

【问题讨论】:

  • 我知道这并不能解决您的问题,但我听说 jar 资源的行为取决于 jar 的运行方式。我强烈建议将您的资源与 jar 分开打包,这样可以省去很多麻烦。
  • 您是否尝试打印出 stringsDirectory 参数的值?另外,我假设您确认 xml 文件实际上在 jar 文件中?
  • @AmirAfghani 我已经使用 WinRar 手动提取了 jar 文件,并且找到了 xml 文件的确切位置。
  • 我想建议您使用Java 内置的ZipFile 文件类,那么。 docs.oracle.com/javase/7/docs/api/java/util/zip/ZipFile.html他们会允许你打开一个罐子,这真的是一个拉链。

标签: java jar


【解决方案1】:

JAR 文件实际上是 ZIP 文件,因此只需将文件视为 ZIP 文件,就像 @Jamie 建议的那样。

【讨论】:

  • 我有一个问题:一旦我得到目录的ZipEntry 对象,我如何列出ZipEntry 中的所有文件?
  • 我发现了如何获得正确的ZipEntry 但是我认为我的代码存在问题,因为 jar 文件的最后一个 ZipEntry 被忽略:我正在添加新代码问题。
  • 之后简单地循环一个额外的时间怎么样?可能您的循环条件在需要之前停止了一圈。
  • 我已经尝试在循环之后手动调用entries.nextElement() 方法,但我得到的只是一个异常,说没有更多元素了......
  • 我也使用 Java 8 Stream API 而不是循环解决了这个问题!
猜你喜欢
  • 2015-06-15
  • 1970-01-01
  • 2018-06-04
  • 2012-11-22
  • 2011-03-23
相关资源
最近更新 更多