Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在jar中运行时从资源文件夹获取文件名列表_Java_Jar_Fileinputstream - Fatal编程技术网

Java 在jar中运行时从资源文件夹获取文件名列表

Java 在jar中运行时从资源文件夹获取文件名列表,java,jar,fileinputstream,Java,Jar,Fileinputstream,我在“resource/Json/templates”文件夹中有一些Json文件。我想读取这些Json文件。到目前为止,下面的代码片段允许我在IDE中运行程序时这样做,但在jar中运行时失败 JSONParser parser = new JSONParser(); ClassLoader loader = getClass().getClassLoader(); URL url = loader.getResource(templateDirectory); String pa

我在“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();
}
JSONParser=newjsonparser();
ClassLoader=getClass().getClassLoader();
URL=loader.getResource(templateDirectory);
字符串路径=url.getPath();
File[]files=新文件(路径).listFiles();
PipelineTemplateRepo PipelineTemplateRepo=新的pipelinetemplaterepimpl();
文件模板文件;
JSONObject templateJson;
PipelineTemplateVo templateFromFile;
PipelineTemplateVo templateFromDB;
字符串模板名;
对于(int i=0;i
任何帮助都将不胜感激


非常感谢。

首先,请记住JAR是Zip文件,因此不解压缩就无法从中取出单个的
文件。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);
}
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()));
}
或者,您可以获取正在运行的Jar,遍历其条目,收集
resource/json/templates/
的子条目,然后从这些条目中获取流。注意:这只在运行Jar时有效,在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);
}
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()));
}
public void runOrSomething()抛出IOException、URISyntaxException{
//…其他逻辑。。。
最终字符串path=“resource/json/templates/”;
谓词pred=(j)->!j.isDirectory()和&j.getName().startsWith(路径);
try(JarFile jar=newtest().getThisJar()){
List resources=getEntriesUnderPath(jar,pred);
for(JarEntry:resources){
System.out.println(entry.getName());
try(InputStream=jar.getInputStream(entry)){
//JarEntry流在其JarFile关闭时关闭,
//所以你必须在关闭“jar”之前使用它们
templateJson=(JSONObject)parser.parse(is);
//…其他逻辑。。。
}
}
}
}
//得到所有的孩子,而不仅仅是直接的
//路径通常应以反斜杠结束
公共静态列表getEntriesUnderPath(JarFile jar,谓词pred)
{
列表=新建LinkedList();
枚举条目=jar.entries();
//必须遍历所有Jar条目
while(entries.hasMoreElements()){
JarEntry=entries.nextElement();
if(预测试(输入))
列表。添加(条目);
}
退货清单;
}
public JarFile getThisJar()引发IOException,URISyntaxException{
URL URL=getClass().getProtectionDomain().getCodeSource().getLocation();
返回新文件(新文件(url.toURI());
}

我希望这会有所帮助。

假设在类路径中,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);

请提供更多细节。错误消息是什么?您是如何创建jar文件的?对不起,我用maven build创建了一个jar。“文件”是空的。基本答案是,你不能。Jar文件是Zip文件,除非您能够在运行时识别包含相关资源的Zip文件的位置,否则您不能列出它的内容。您的代码不应该假设Jar文件的名称或位置,因为它将您的代码耦合到变量状态。相反,在构建/打包Jar时,生成一个文件列表并将其保存到一个已知的文件/位置,然后将其存储在Jar文件中。在运行时,阅读此资源,然后您将获得其他资源的列表files@Juvenik我的代码不适合你吗?请让我知道,我也许能帮上忙。嗨,我试过了,但是我得到了以下错误:com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171),com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157),java.nio.file.path.get(path.java:143)@Juvenik对不起,我曾希望这比xtratic的解决方案更容易;它看起来很有道理。