2013-04-16 7 views
6

Ich möchte nur eine Datei in mein Programm lesen. Die Datei befindet sich ein Verzeichnis über dem Arbeitsverzeichnis bei "../f.fsh". So ist der folgende Code ordnungsgemäß ausgeführt wird, wenn ich es in der IDE ausführenWarum funktioniert getResourceAsStream() in der IDE, aber nicht in der JAR?

String name="../f.fsh"; 
InputStream is = getClass().getResourceAsStream(name); 
InputStreamReader isreader=new InputStreamReader(is);//CRASHES HERE WITH NULL POINTER EXCEPTION 
BufferedReader br = new BufferedReader(isreader); 

aber wenn ich eine JAR-Datei erstellen, die f.fsh in der es hat Reißverschluss und führen Sie es, es stürzt ab, wenn die Input zu schaffen, da die Input ist Null.

Ich habe eine Reihe von Antworten auf Fragen zu Eingabestreams und JAR-Dateien gelesen, und ich habe herausgefunden, dass ich relative Pfade verwenden sollte, aber das mache ich schon. Von was ich verstehe, kann getResourceAsStream() Dateien relativ zum Stamm des Projekts finden, das ist was ich will. Warum funktioniert es nicht in der JAR? Was läuft falsch, wie kann ich es beheben?

Hat es mit dem Klassenpfad zu tun? Ich dachte, das war nur für die Aufnahme von Dateien außerhalb des jar ausgeführt werden.

Ich habe auch versucht, aber immer noch, schlagen fehl, wenn Sie einen Schrägstrich bei der Umsetzung:

InputStream is = getClass().getResourceAsStream("\\"+name); 

ich sah: How to get a path to a resource in a Java JAR file andfound, dass der Inhalt eines JAR kann necesarily nicht als Datei zugänglich sein. Also versuchte ich es mit dem Kopieren der Datei relativ zum Jar (ein Verzeichnis nach oben aus dem Jar), ​​und das schlägt immer noch fehl. Auf jeden Fall möchte ich meine Dateien im Glas lassen und sie dort lesen können. Ich weiß nicht, was schief läuft.

Antwort

3

Wenn .. in Class.getResourceAsStream() funktioniert, während von Eclipse ausgeführt wird, ist es ein Fehler in Eclipse. Eclipse und andere IDEs implementieren benutzerdefinierte Klassenladeprogramme, um Ressourcen zur Laufzeit aus dem Projekt abzurufen. Es sieht so aus, als ob die Class Loader-Implementierung in Eclipse nicht alle notwendigen Validierungen bei der Eingabe der getResourceAsStream() Methode durchführt. In diesem Fall ist der Fehler zu Ihren Gunsten, aber Sie müssen immer noch überdenken, wie Sie Ihre Ressourcen strukturieren, damit Ihr Code in allen Fällen funktioniert.

+0

Danke, das macht Sinn. Ich habe meine Dateispeicherorte geändert, und wo sich meine Ressourcen befinden, und es konnte diesen Fehler in der JAR-Datei beheben. Ich hätte nie gedacht, dass Eclipse einen Bug zu meinen Gunsten hatte. Ich danke dir sehr! – AAB

8

Sie können .. mit Class.getResourceAsStream() nicht verwenden.

Um eine Ressource f.fsh im gleichen Paket wie die Klasse zu laden, SomeClass.class.getResourceAsStream("f.fsh")

verwenden, um eine Ressource f.fsh in einem Teilpaket foo.bar des Pakets der Klasse, verwenden zu laden SomeClass.class.getResourceAsStream("foo/bar/f.fsh")

Zum eine Ressource f.fsh in jedem Paket com.company.foo.bar laden, verwenden SomeClass.class.getResourceAsStream("/com/company/foo/bar/f.fsh")

Dies wird in der Javadoc- des getResource() Verfahren beschrieben, obwohl es Beispiele fehlt.

+0

Danke für die Antwort, ich sehe, was Sie über das Hinzufügen eines Schrägstrichs oder nicht zum Anfang sagen. Es funktioniert nicht mit ".."? Es scheint das ".." zu verstehen, wenn ich es von der Finsternis aus führe. Aber es ist einfach nicht kompatibel mit dem Glas? Weißt du warum es ist? – AAB

+1

Ich bin sogar überrascht, dass es funktioniert, wenn aus einem Glas verwendet wird. Das Javadoc lässt nicht zu .. verwendet werden. Es ist so, wie es entworfen wurde. –

+0

Habe gerade das gleiche Problem erlebt. Meine Vermutung wäre, dass das Argument, wenn es von Klassendateien auf der Festplatte ausgeführt wird, einfach an eine OS-Funktion gesendet (leicht geparst) wird und daher funktioniert, obwohl es dem Protokoll nicht folgt. Dies wurde mit SE6 btw getestet. – user

Verwandte Themen