2013-08-05 16 views
38

Ich habe Dateien im Ressourcenordner. Zum Beispiel, wenn ich Datei von Ressourcenordner erhalten müssen, kann ich wie folgt aus:Warum ist meine URI nicht hierarchisch?

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

Ich habe getestet und alles funktioniert!

Der Weg ist

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

Aber, Wenn ich erstellen JAR-Datei, zu verwenden, Maven:

mvn package 

... und dann meine app starten:

java -jar MyJar.jar 

Ich habe die Fehler folgende:

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) 

... und den Pfad der Datei ist:

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

Diese Ausnahme tritt auf, wenn ich versuche Datei von Ressourcenordner zu erhalten. An dieser Linie. Warum? Warum ist das Problem in der JAR-Datei? Was denken Sie?

Gibt es eine andere Möglichkeit, den Pfad zum Ressourcenordner abzurufen?

+4

Sie können einen Blick darauf werfen: http://stackoverflow.com/questions/10144210/java-jar-file-use-resource-errors-uri-is-not-hierarchical und die akzeptierte Antwort. – cyroxx

Antwort

57

sollten Sie

getResourceAsStream(...); 

verwendet werden, wenn die Ressource als jar/Krieg oder jede andere Datei-Paket für diese Angelegenheit gebündelt.

Die Sache ist, ein Jar ist eine einzelne Datei (eine Art wie eine Zip-Datei), die viele Dateien zusammenhält. Aus Os Pov, ist es eine einzige Datei und wenn Sie auf eine part of the file (Ihre Bilddatei) zugreifen möchten, müssen Sie es als Stream verwenden.

Documentation

10

Hier ist eine Lösung für Eclipse RCP/Plugin-Entwickler:

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

Es ist sehr wichtig FileLocator.toFileURL(fileURL) zu verwenden, anstatt resolve(fileURL) , verursachen, wenn das Plug-in ein Gefäß gepackt wird dies dazu führen, Eclipse zum Erstellen einer entpackten Version an einem temporären Speicherort, sodass auf das Objekt über Datei zugegriffen werden kann. Zum Beispiel, ich denke, Lars Vogel hat einen Fehler in seinem Artikel - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/

+3

Danke, ich schulde dir ein Bier, Vogellas Artikel braucht ein Update. –

+0

@Vladllie Liebe, dass es dir geholfen hat ;-) –

+0

http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcore % 2Fruntime% 2FFileLocator.html Diese Lösung scheint plattformabhängig zu sein. Gibt es eine Möglichkeit, etwas ähnliches von IntelliJ zu erreichen, ohne "org.eclipse.core.runtime.FileLocator" importieren zu müssen? – Kwoinkwoin

0

Ich habe das gleiche Problem, wenn ich an einem Projekt in meiner Firma arbeitete. Zunächst einmal ist der URI nicht hierarchisch. Problem ist, weil Sie wahrscheinlich "/" als Dateitrenner verwenden.

Sie müssen sich daran erinnern, dass "/" für Windows und von OS zu OS, es ändert sich, kann es unter Linux anders sein. Verwenden Sie daher File.Seperator.

So

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

die URI nicht hierarichal kann entfernen verwenden. Aber jetzt können Sie sich einer Nullzeiger-Ausnahme gegenübersehen. Ich habe viele verschiedene Wege ausprobiert und dann die JarEntries-Klasse benutzt, um sie zu lösen.

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

Hier müssen Sie den Jar-Namen explizit angeben. Also benutze diesen Code, das dir Verzeichnis und Unterverzeichnis innerhalb des Ordners in jar gibt.

Verwandte Themen