java 在jar中运行时从资源文件夹中获取文件名列表[重复]

dba5bblo  于 2023-05-27  发布在  Java
关注(0)|答案(2)|浏览(131)

此问题已在此处有答案

Get a list of resources from classpath directory(16个回答)
1小时前关闭
我在“resource/json/templates”文件夹中有一些JSON文件。我想读这些JSON文件。到目前为止,下面的代码片段允许我在IDE中运行程序时这样做,但当我在jar中运行它时,它失败了。

JSONParser parser = new JSONParser();
  ClassLoader loader = getClass().getClassLoader();
  URL url = loader.getResource(templateDirectory);
  String path = url.getPath();
  File[] files = new File(path).listFiles();
  PipelineTemplateRepo pipelineTemplateRepo = new PipelineTemplateRepoImpl();
  File templateFile;
  JSONObject templateJson;
  PipelineTemplateVo templateFromFile;
  PipelineTemplateVo templateFromDB;
  String templateName;

  for (int i = 0; i < files.length; i++) {
    if (files[i].isFile()) {
      templateFile = files[i];
      templateJson = (JSONObject) parser.parse(new FileReader(templateFile));
      //Other logic
    }
  }
}
catch (Exception e) {
  e.printStackTrace();
}

任何帮助将不胜感激。
多谢了。

rryofs0p

rryofs0p1#

假设在类路径中,在jar中目录以/json开始(/resource是根目录),它可能是这样的:

URL url = getClass().getResource("/json");
    Path path = Paths.get(url.toURI());
    Files.walk(path, 5).forEach(p -> System.out.printf("- %s%n", p.toString()));

这将使用jar:file://... URL,并在其上打开一个虚拟文件系统。
检查jar是否确实使用了该路径。
可以根据需要进行阅读。

BufferedReader in = Files.newBufferedReader(p, StandardCharsets.UTF_8);
laik7k3q

laik7k3q2#

首先,请记住,Jars是Zip文件,因此如果不解压缩它,您无法从中获取单个File。Zip文件并没有目录,所以这并不像获取目录的子目录那么简单。
这是一个有点困难的问题,但我也很好奇,经过研究,我想出了以下几点。
首先,您可以尝试将资源放入Jar中嵌套的平面Zip文件(resource/json/templates.zip)中,然后从该zip文件加载所有资源,因为您知道所有zip条目都将是您想要的资源。即使在IDE中也应该可以工作。

String path = "resource/json/templates.zip";
ZipInputStream zis = new ZipInputStream(getClass().getResourceAsStream(path));
for (ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) {
    // 'zis' is the input stream and will yield an 'EOF' before the next entry
    templateJson = (JSONObject) parser.parse(zis);
}

或者,您可以获取正在运行的Jar,遍历它的条目,收集resource/json/templates/的子条目,然后从这些条目中获取流。注意:* 这将只在运行Jar时起作用 *,添加一个检查,以便在IDE中运行时运行其他内容。

public void runOrSomething() throws IOException, URISyntaxException {
    // ... other logic ...
    final String path = "resource/json/templates/";
    Predicate<JarEntry> pred = (j) -> !j.isDirectory() && j.getName().startsWith(path);

    try (JarFile jar = new Test().getThisJar()) {
        List<JarEntry> resources = getEntriesUnderPath(jar, pred);
        for (JarEntry entry : resources) {
            System.out.println(entry.getName());
            try (InputStream is = jar.getInputStream(entry)) {
                // JarEntry streams are closed when their JarFile is closed,
                // so you must use them before closing 'jar'
                templateJson = (JSONObject) parser.parse(is);
                // ... other logic ...
            }
        }
    }
}

// gets ALL the children, not just direct
// path should usually end in backslash
public static List<JarEntry> getEntriesUnderPath(JarFile jar, Predicate<JarEntry> pred)
{
    List<JarEntry> list = new LinkedList<>();
    Enumeration<JarEntry> entries = jar.entries();

    // has to iterate through all the Jar entries
    while (entries.hasMoreElements()) {
        JarEntry entry = entries.nextElement();
        if (pred.test(entry))
            list.add(entry);
    }
    return list;
}

public JarFile getThisJar() throws IOException, URISyntaxException {
    URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
    return new JarFile(new File(url.toURI()));
}

希望这能帮上忙。

相关问题