Um Ressourcen wie Grafiken oder Konfigurationsdateien aus Jar-Archiven zu laden gibt es eine Methoden am Class-Objekt: getResourceAsStream().
class java.lang.Class
implements Serializable, GenericDeclaration, Type, AnnotatedElement
– InputStream getResourceAsStream(String name)
Gibt einen Eingabestrom auf die Datei mit dem Namen name zurück, oder null, falls es keine Ressource mit dem Namen im Klassepfad gibt.
Da der Klassenlader die Ressource findet, entdeckt er alle Dateien, die im Pfad des Klassenladers eingetragen sind. Das gilt auch für Jar-Archive, weil dort vom Klassenlader alles verfügbar ist. Die Methode getResourceAsStream() liefert auch null, wenn die Sicherheitsrichtlinien das Lesen verbieten. Da die Methode keine Ausnahme auslöst, muss auf jeden Fall getestet werden, ob die Rückgabe ungleich null war.
Das folgende Programm liest ein Byte ein und gibt es auf dem Bildschirm aus:
package com.tutego.insel.io.stream;
import java.io.*;
import java.util.Objects;
public class GetResourceAsStreamDemo {
public static void main( String[] args ) {
String filename = "onebyte.txt";
InputStream is = Objects.requireNonNull(
GetResourceAsStreamDemo.class.getResourceAsStream( filename ),
"Datei gibt es nicht!" );
try {
System.out.println( is.read() ); // 49
}
catch ( IOException e ) {
e.printStackTrace();
}
}
}
Die Datei onebyte.txt befindet sich im gleichen Pfad wie auch die Klasse, liegt also in com/tutego/insel/io/stream/onebyte.txt. Liegt sie zum Beispiel im Wurzelverzeichnis des Pakets, muss sie mit "/onebyte.txt" angegeben werden. Liegen die Ressourcen außerhalb des Klassenpfades, können sie nicht gelesen werden. Der große Vorteil ist aber, dass die Methode alle Ressourcen anzapfen kann, die über den Klassenlader zugänglich sind, und das ist insbesondere der Fall, wenn die Dateien aus Jar-Archiven kommen – hier gibt es keinen üblichen Pfad im Dateisystem, der hört in der Regel beim Jar-Archiv selbst auf.
Zum Nutzen der getResourceAsStream()-Methoden ist ein Class-Objekt nötig, was wir in unserem Fall über Klassenname.class besorgen. Das ist nötig, weil die Methode main() statisch ist. Andernfalls kann innerhalb von Objektmethoden auch getClass() eingesetzt werden, eine Methode, die jede Klasse aus der Basisklasse java.lang.Object erbt.