2009-02-21 11 views
66

In meiner Java-App muss ich einige Dateien und Verzeichnisse bekommen.offene Ressource mit relativem Pfad in Java

Dies ist die Programmstruktur:

./main.java 
./package1/guiclass.java 
./package1/resources/resourcesloader.java 
./package1/resources/repository/modules/ -> this is the dir I need to get 
./package1/resources/repository/SSL-Key/cert.jks -> this is the file I need to get 

guiclass lädt die resourcesloader Klasse, die meine Ressourcen geladen werden (Verzeichnis und Datei).

über die Datei, habe ich versucht,

resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString() 

, um den tatsächlichen Pfad zu bekommen, aber auf diese Weise nicht funktioniert ...

über das dir mir keine Ahnung, wie zu tun ..

Vorschläge? Danke.

+1

class.getClass() ist nicht das gleiche wie class.getClassLoader(). Es gibt auch eine andere Lösung: getResourceAsStream() verwendet eine Klasse im selben Paket wie Ihre Ressource. Für weitere Details: http://tshikatshikaaa.blogspot.nl/2012/07/maven-how-to-access-filesdata-in.html. – JVerstry

+0

Siehe auch http://stackoverflow.com/questions/204784/how-to-construct-a-relative-path-in-java-from-two-absolute-paths-orls – Vadzim

Antwort

37

Geben Sie den Pfad relativ zum Classloader an, nicht die Klasse, von der Sie den Loader erhalten. Zum Beispiel:

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString(); 
1

Führen Sie die folgende Arbeit durch?

Gibt es einen Grund, dass Sie den vollständigen Pfad einschließlich des Pakets nicht angeben können?

2
resourcesloader.class.getClass() 

Kann nach unten gebrochen werden:

Class<resourcesloader> clazz = resourceloader.class; 
Class<Class> classClass = clazz.getClass(); 

Was bedeutet, Sie versuchen, die Ressource zu laden, eine Bootstrap-Klasse.

Stattdessen möchten Sie wahrscheinlich so etwas wie:

resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString() 

Wenn nur javac über Aufruf statische Methoden gewarnt auf nicht-statische Kontexte ...

7

Wenn Sie ‚getResource‘ auf einer Klasse, einer relativen Der Pfad wird basierend auf dem Paket aufgelöst, in dem sich die Klasse befindet. Wenn Sie 'getResource' in einem ClassLoader verwenden, wird ein relativer Pfad basierend auf dem Stammordner aufgelöst.

Wenn Sie einen absoluten Pfad verwenden, beginnen beide getResource-Methoden im Stammordner.

+0

Vergessen Sie nicht die Auswirkungen von '' '' _ '' – Gilberto

+0

@nbeyer Warum beginnt die Verwendung von 'getResource' mit absolutem Pfad im Stammordner? Ist der Zweck des absoluten Weges nicht absolut **? –

126

Ich hatte Probleme mit der getClass().getResource("filename.txt") Methode. Wenn Sie nach dem Lesen der Java-Dokumentationsanweisungen nicht in demselben Paket wie die Klasse, auf die Sie zugreifen möchten, von der Ressource zugreifen, müssen Sie einen relativen Pfad angeben, der mit '/' beginnt. Die empfohlene Strategie besteht darin, Ihre Ressourcendateien in einem Ordner "Ressourcen" im Stammverzeichnis ablegen.Wenn Sie die Struktur So zum Beispiel haben:

src/main/com/mycompany/myapp 

dann können Sie einen Ressourcen-Ordner hinzufügen, wie von Maven empfohlen in:

src/main/resources 

außerdem können Sie Unterordner in den Ordner Ressourcen hinzufügen

src/main/resources/textfiles 

und sagen, dass Ihre Datei heißt myfile.txt, so haben Sie

src/main/resources/textfiles/myfile.txt 

Jetzt ist hier, wo das Problem dummer Pfad kommt. Sagen Sie, Sie haben eine Klasse in Ihrem com.mycompany.myapp package, und Sie möchten auf die myfile.txt Datei aus Ihrem Ressourcenordner zugreifen. Einige sagen, dass Sie das geben:

"/main/resources/textfiles/myfile.txt" path 

oder

"/resources/textfiles/myfile.txt" 

beides falsch sind.

myapp/target/classes 

Ordner: Nachdem ich mvn clean compile lief, werden die Dateien und Ordner in die kopiert. Aber der Ressourcenordner ist nicht da, nur die Ordner im Ressourcenordner. Sie haben also:

myapp/target/classes/textfiles/myfile.txt 

myapp/target/classes/com/mycompany/myapp/* 

so der korrekte Pfad zum getClass().getResource("") Methode zu geben:

"/textfiles/myfile.txt" 

hier ist es:

getClass().getResource("/textfiles/myfile.txt") 

Dies wird nicht mehr null zurück, wird aber Gib deine Klasse zurück. Ich hoffe, das hilft jemandem. Es ist seltsam für mich, dass der Ordner "resources" nicht kopiert wird, sondern nur die Unterordner und Dateien direkt im Ordner "resources". Es scheint mir logisch, dass der "resources" Ordner würde auch unter "myapp/target/classes"

+1

In meinem 'target/classes' kann ich nur Dateien unter Hauptressourcen sehen und nicht Ressourcen testen. Warum? – Ava

+0

@Ava Fügen Sie den Testordner als Ihren Quellordner hinzu und Sie können loslegen! –

8

@GianCarlo finden: Sie können Systemeigenschaft user.dir versuchen aufrufen, die Sie Wurzel Ihrer Java-Projekt geben und dann diesen Weg Sie anhängen zu Ihrem relativer Pfad zum Beispiel:

String root = System.getProperty("user.dir"); 
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt 
String abspath = root+filepath; 



// using above path read your file into byte [] 
File file = new File(abspath); 
FileInputStream fis = new FileInputStream(file); 
byte []filebytes = new byte[(int)file.length()]; 
fis.read(filebytes); 
+0

OP wollte eine Ressource im Klassenpfad finden (am wahrscheinlichsten in einem jar, das während des Builds generiert wurde). Diese Methode bietet keine Möglichkeit, dieses Ziel zu erreichen - Sie können eine Datei nicht auf eine Ressource innerhalb einer JAR-Datei verweisen, sondern nur auf einen korrekten Eintrag im Dateisystem (z. B. das JAR selbst). – Attila

29

In der Hoffnung für diejenigen mit zusätzlichen Informationen, die dies als andere so schnell nicht abholen, ich mag mein Szenario schaffen, wie es ein etwas anderes Setup hat. Mein Projekt war Setup mit der folgenden Verzeichnisstruktur (mit Eclipse):

 
Project/ 
    src/    // application source code 
    org/ 
     myproject/ 
     MyClass.java 
    test/    // unit tests 
    res/    // resources 
    images/   // PNG images for icons 
     my-image.png 
    xml/    // XSD files for validating XML files with JAXB 
     my-schema.xsd 
    conf/    // default .conf file for Log4j 
     log4j.conf 
    lib/    // libraries added to build-path via project settings 

ich Probleme hatte meine Ressourcen aus dem res Verzeichnis zu laden. Ich wollte alle meine Ressourcen getrennt von meinem Quellcode (einfach für die Verwaltung/Organisation).Also, was ich tun musste, war hinzufügen die res Verzeichnis auf den Build-Pfad und dann Zugriff auf die Ressource über:

static final ClassLoader loader = MyClass.class.getClassLoader(); 

// in some function 
loader.getResource("images/my-image.png"); 
loader.getResource("xml/my-schema.xsd"); 
loader.getResource("conf/log4j.conf"); 

HINWEIS: Die / von Anfang an von der weggelassen Ressourcen-String, weil ich ClassLoader.getResource(String) anstelle von Class.getResource(String) verwende.

+1

. + 1 für Vorschlag ClassLoader – pyb

+0

Beste Antwort zu diesem Thema! Der Tipp, nicht '/' am Anfang eines Ressourcenpfads zu verwenden, war der Schlüssel! – Kayhadrin

1

Gehen mit den beiden Antworten wie oben erwähnt. Die erste

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString(); 
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString() 

Sollte ein und dasselbe Ding sein?

3

Für diejenigen, die Eclipse + Maven verwenden. Angenommen, Sie versuchen, auf die Datei images/pic.jpg in src/main/resources zuzugreifen. So machen Sie das:

ClassLoader loader = MyClass.class.getClassLoader(); 
File file = new File(loader.getResource("images/pic.jpg").getFile()); 

ist vollkommen korrekt, kann aber zu einer Nullzeigerausnahme führen. Offenbar erkennt Eclipse die Ordner in der Maven-Verzeichnisstruktur nicht sofort als Quellordner. Indem ich den Ordner src/main/resources aus der Liste der Quellordner des Projekts lösche und wieder einfüge (Projekt> Eigenschaften> Java-Buildpfad> Quelle> Ordner entfernen/hinzufügen), konnte ich das Problem lösen.

0

Ich habe eine kleine Änderung an @ onliner.cones einem Liner (durch Hinzufügen von .getFile()) gemacht, um Nullzeiger Ausnahme zu vermeiden, und den Pfad zum Datenverzeichnis. Hier ist, was für mich gearbeitet:

String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next(); 
0

verwenden:

resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**