web-dev-qa-db-ja.com

URIが階層的ではないのはなぜですか?

リソースフォルダーにファイルがあります。たとえば、リソースフォルダーからファイルを取得する必要がある場合は、次のようにします。

File myFile= new File(MyClass.class.getResource(/myFile.jpg).toURI());             
System.out.println(MyClass.class.getResource(/myFile.jpg).getPath());

テスト済みおよびすべて動作

パスは

/D:/Java/projects/.../classes/X/Y/Z/myFile.jpg

しかし、を使用してjarファイルを作成する場合、Maven

mvn package

...そしてアプリを起動します:

Java -jar MyJar.jar

私は次のエラーがあります:

Exception in thread "Thread-4" Java.lang.RuntimeException: ხელმოწერის განხორციელება შეუძლებელია
Caused by: Java.lang.IllegalArgumentException: URI is not hierarchical
        at Java.io.File.<init>(File.Java:363)

...およびファイルのパス

file:/D:/Java/projects/.../target/MyJar.jar!/X/Y/Z/myFile.jpg

この例外は、リソースフォルダーからファイルを取得しようとすると発生します。この行で。どうして? JARファイルにその問題があるのはなぜですか?どう思いますか?

リソースフォルダーのパスを取得する別の方法はありますか?

46
grep

あなたが使用する必要があります

getResourceAsStream(...);

リソースがjar/warまたはその他の単一ファイルパッケージとしてバンドルされている場合。

参照してください、jarは多くのファイルを一緒に保持する単一のファイル(Zipファイルのようなもの)です。 OsのPOVから、その単一のファイルであり、part of the file(画像ファイル)ストリームとして使用する必要があります。

ドキュメント

70
rocketboy

Eclipse RCP /プラグイン開発者向けのソリューションは次のとおりです。

_Bundle bundle = Platform.getBundle("resource_from_some_plugin");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
   URL resolvedFileURL = FileLocator.toFileURL(fileURL);

   // We need to use the 3-arg constructor of URI in order to properly escape file system chars
   URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null);
   File file = new File(resolvedURI);
} catch (URISyntaxException e1) {
    e1.printStackTrace();
} catch (IOException e1) {
    e1.printStackTrace();
}
_

FileLocator.toFileURL(fileURL)ではなくresolve(fileURL)を使用することが非常に重要です。これは、プラグインをjarにパックすると、Eclipseが一時的な場所にアンパックバージョンを作成し、オブジェクトがFileを使用してアクセスします。たとえば、Lars Vogelの記事に誤りがあると思います- http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/

11
Ilya Buziuk

会社でプロジェクトに取り組んでいたとき、私は同じ問題に直面しています。まず第一に、URIは階層的ではありません。おそらく、ファイル区切り文字として「/」を使用しているためです。

「/」はWindows用であり、OSごとに変更されることを覚えておく必要があります。Linuxでは異なる場合があります。したがって、File.seperatorを使用します。

を使用して

this.getClass().getClassLoader().getResource("res"+File.separator+"secondFolder")

hierarichalではなくURIを削除できます。しかし、Null Pointer Exceptionに直面する可能性があります。さまざまな方法を試した後、JarEntriesクラスを使用して解決しました。

File jarFile = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        String actualFile = jarFile.getParentFile().getAbsolutePath()+File.separator+"Name_Of_Jar_File.jar";
        System.out.println("jarFile is : "+jarFile.getAbsolutePath());
        System.out.println("actulaFilePath is : "+actualFile);
        final JarFile jar = new JarFile(actualFile);
        final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
        System.out.println("Reading entries in jar file ");
        while(entries.hasMoreElements()) {
            JarEntry jarEntry = entries.nextElement();
            final String name = jarEntry.getName();
            if (name.startsWith("Might Specify a folder name you are searching for")) { //filter according to the path
                System.out.println("file name is "+name);
                System.out.println("is directory : "+jarEntry.isDirectory());
                File scriptsFile  = new File(name);
                System.out.println("file names are : "+scriptsFile.getAbsolutePath());

            }
        }
        jar.close();

ここで明示的にjar名を指定する必要があります。したがって、このコードを使用すると、jar内のフォルダー内のディレクトリとサブディレクトリが得られます。

2
Prateek Mishra