web-dev-qa-db-de.com

Liest die Datei mit Java 7 NIO aus dem Klassenpfad

Ich habe eine Weile dafür gegoogelt, aber alle Ergebnisse deuten auf NIO-Lösungen vor Java 7 hin. Ich habe das NIO-Zeug verwendet, um Dateien von einer bestimmten Stelle im Dateisystem einzulesen, und es war so viel einfacher als zuvor (Files.readAllBytes(path)). Jetzt möchte ich eine Datei einlesen, die in meinem WAR und im Klassenpfad gepackt ist. Das machen wir derzeit mit folgendem Code:

Input inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

/* iterate through the input stream to get all the bytes (no way to reliably find the size of the 
 *     file behind the inputStream (see http://docs.Oracle.com/javase/6/docs/api/Java/io/InputStream.html#available()))
 */
int byteInt = -1;
try
{
    byteInt = inputStream.read();
    while (byteInt != -1)
    {
        byteStream.write(byteInt);
        byteInt = inputStream.read();
    }

    byteArray = byteStream.toByteArray();
    inputStream.close();
    return byteArray;
}
catch (IOException e)
{
    //...
}

Während dies funktioniert, hatte ich gehofft, dass es eine einfachere/bessere Möglichkeit gibt, dies mit dem NIO-Material in Java 7 zu tun. Ich schätze, ich muss ein Path -Objekt abrufen, das diesen Pfad auf dem Klassenpfad darstellt. aber ich bin nicht sicher, wie ich das machen soll.

Ich entschuldige mich, wenn dies eine super einfache Sache ist. Ich finde es einfach nicht heraus. Danke für die Hilfe.

13
dnc253

Ein Pfad repräsentiert eine Datei im Dateisystem. Es hilft nicht, eine Ressource aus dem Klassenpfad zu lesen. Was Sie suchen, ist eine Hilfsmethode, die alles aus einem Stream liest (effizienter als das, was Sie tun) und in ein Byte-Array schreibt. Apache commons-io oder Guava können Ihnen dabei helfen. Zum Beispiel mit Guave:

byte[] array = 
    ByteStreams.toByteArray(this.getClass().getClassLoader().getResourceAsStream(resourceName));

Wenn Sie Guava oder commons-io nicht nur deshalb zu Ihren Abhängigkeiten hinzufügen möchten, können Sie deren Quellcode jederzeit lesen und in Ihre eigene Hilfsmethode duplizieren.

7
JB Nizet

Das funktioniert bei mir.

import Java.nio.file.Files;
import Java.nio.file.Paths;

// fileName: foo.txt which lives under src/main/resources
public String readFileFromClasspath(final String fileName) throws IOException, URISyntaxException {
    return new String(Files.readAllBytes(
                Paths.get(getClass().getClassLoader()
                        .getResource(fileName)
                        .toURI())));
}
26
shreyas

Soweit ich weiß, möchten Sie eine ReadableByteChannel für Ihre Ressource öffnen, damit Sie sie mit NIO lesen können.

Dies sollte ein guter Anfang sein,

// Opens a resource from the current class' defining class loader
InputStream istream = getClass().getResourceAsStream("/filename.txt");

// Create a NIO ReadableByteChannel from the stream
ReadableByteChannel channel = Java.nio.channels.Channels.newChannel(istream);
2

Sie sollten sich ClassLoader.getResource() ansehen. Dies gibt eine URL zurück, die die Ressource darstellt. Wenn es lokal für das Dateisystem ist, ist es eine file:// URL. An diesem Punkt können Sie das Schema usw. entfernen, und dann haben Sie den Dateinamen, mit dem Sie tun können, was Sie wollen.

Wenn es sich jedoch nicht um einen file: // - Pfad handelt, können Sie auf den normalen InputStream zurückgreifen.

1
Will Hartung