まず、Jarファイルは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);
}
また、あなたは、実行中の瓶を取得し、そのエントリを反復処理し、それらのエントリからのストリームを取得し、その後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()));
}
これが役立ちます。
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ファイルにディレクトリが(/リソースは、ルートディレクトリです)/ JSONで始まり、それはのような可能性があると仮定すると
もっと詳しく教えてください。エラーメッセージとは何ですか? jarファイルをどのように作成しましたか? –
申し訳ありませんが、私はMavenビルドでjarファイルを作成しました。そして、「ファイル」はnullになります。 – Juvenik
基本的な答えはできません。 JarファイルはZipファイルですが、実行時に問題のリソースを含むZipファイルの場所を特定できない限り、その内容はリストできません。コードでは、Jarファイルの名前または場所について、コードを可変状態に結合するための前提はありません。代わりに、Jarをビルド/パッケージ化するときに、ファイルリストを生成し、それをよく知られているファイル/場所に保存し、これをJarファイルに保存します。実行時に、このリソースを読んでから、他のファイルのリストが表示されます – MadProgrammer