Juv*_*nik 10 java jar fileinputstream
我在“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();
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激。
多谢。
假设在类路径中,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()));
Run Code Online (Sandbox Code Playgroud)
这使用jar:file://...URL,并在其上打开虚拟文件系统。
检查 jar 确实使用该路径。
可以根据需要进行阅读。
BufferedReader in = Files.newBufferedReader(p, StandardCharsets.UTF_8);
Run Code Online (Sandbox Code Playgroud)
首先,请记住,Jars 是 Zip 文件,因此您无法在File不解压缩的情况下从中取出单个文件。Zip 文件并不完全具有目录,因此它不像获取目录的子目录那么简单。
这有点困难,但我也很好奇,经过研究,我得出了以下结论。
首先,您可以尝试将资源放入resource/json/templates.zip嵌套在 Jar 中的平面 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);
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以获取正在运行的 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()));
}
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助。