2013-08-05 24 views
38

リソースフォルダにファイルがあります。私はリソースフォルダからファイルを取得する必要がある場合たとえば、私はそのようにします:私の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ファイルを作成する場合は、その後、

mvn package 

...と私のアプリを起動します:Mavenの

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ファイルにその問題がありますか?どう思いますか?

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

+4

あなたはこれを見ているかもしれません:http://stackoverflow.com/questions/10144210/java-jar-file-use-resource-errors-uris-not-hierarchicalそして受け入れられた答え。 – cyroxx

答えて

57

リソースは、JAR /戦争またはそのことについては、他の単一ファイルのパッケージとしてバンドルされているときは、

getResourceAsStream(...); 

を使用する必要があります。

jarファイルは、たくさんのファイルをまとめた単一のファイル(zipファイルのようなもの)です。 Osのpovからは1つのファイルがあり、part of the file(画像ファイル)にアクセスする場合はストリームとして使用する必要があります。ここで

Documentation

10

の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(); 
} 

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

+3

ありがとう、私はあなたにこの1つのビールを借りている、確かにVogellaの記事は更新が必要です。 –

+0

@Vladllieそれがあなたを助けたことを愛する;-) –

+0

http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcore %2Fruntime%2FFileLocator.html この解決策はプラットフォームに依存しているようです。 "org.eclipse.core.runtime.FileLocator"をインポートすることなく、IntelliJと同様の機能を実現する方法はありますか? – Kwoinkwoin

0

私の会社のプロジェクトで働いていたときと同じ問題に直面する。まず第一に、URIは階層的ではありません。おそらく、ファイルセパレータとして "/"を使用している可能性があります。

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

ので

this.getClass().getClassLoader().getResource("res"+File.seperator+"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のフォルダ内にディレクトリとサブディレクトリを与えます。

関連する問題