So lesen Sie eine Datei in Java

So lesen Sie eine Datei in Java

1. Einführung

In diesem Artikel erfahren Sie, wie Sie mithilfe von Java-Standardklassen eine Datei aus einem Klassenpfad, einer URL oder einer JAR-Datei lesen können.

Weitere Lektüre:

Java - Erstellen Sie eine Datei

So erstellen Sie eine Datei in Java mit JDK 6, JDK 7 mit NIO oder Commons IO.

Read more

Java - In Datei schreiben

Die vielen Möglichkeiten, Daten mit Java in File zu schreiben.

Read more

2. Konfiguration

Wir werden eine Reihe von Testbeispielen nur mit Java-Kernklassen verwenden und in den Tests Assertions mitHamcrest Matchern verwenden.

Tests verwenden eine gemeinsamereadFromInputStream -Smethodik, dieInputStream toString transformiert, um die Bestätigung der Ergebnisse zu erleichtern:

private String readFromInputStream(InputStream inputStream)
  throws IOException {
    StringBuilder resultStringBuilder = new StringBuilder();
    try (BufferedReader br
      = new BufferedReader(new InputStreamReader(inputStream))) {
        String line;
        while ((line = br.readLine()) != null) {
            resultStringBuilder.append(line).append("\n");
        }
    }
  return resultStringBuilder.toString();
}

Beachten Sie, dass es andere Möglichkeiten gibt, das gleiche Ergebnis zu erzielen. Sie könnenthis article für einige Alternativen konsultieren.

3. Datei aus Klassenpfad lesen

In diesem Abschnitt wird erläutert, wie Sie eine Datei lesen, die in einem Klassenpfad verfügbar ist. Wir werden die untersrc/main/resources verfügbaren "fileTest.txt" lesen:

@Test
public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";

    Class clazz = FileOperationsTest.class;
    InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt");
    String data = readFromInputStream(inputStream);

    Assert.assertThat(data, containsString(expectedData));
}

Im obigen Code-Snippet haben wir die aktuelle Klasse zum Laden einer Datei mitgetResourceAsStream method verwendet und den absoluten Pfad der zu ladenden Datei übergeben.

Die gleiche Methode ist auch für eineClassLoader -Sinstanz verfügbar:

ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("fileTest.txt");
String data = readFromInputStream(inputStream);

Wir erhaltenclassLoader für die aktuelle Klasse mitgetClass().getClassLoader().

Der Hauptunterschied besteht darin, dass bei Verwendung vongetResourceAsStream on aClassLoader instance der Pfad ab der Wurzel des Klassenpfads als absolut behandelt wird.

Bei Verwendung gegenClass instance, kann der Pfad relativ zum Paket oder ein absoluter Pfad sein, der durch den führenden Schrägstrich angedeutet wird.

Of course, note that in practice, open streams should always be closed, wie z. B.InputStream in unserem Beispiel:

InputStream inputStream = null;
try {
    File file = new File(classLoader.getResource("fileTest.txt").getFile());
    inputStream = new FileInputStream(file);

    //...
}
finally {
    if (inputStream != null) {
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. Datei mit JDK7 lesen

In JDK7 wurde das NIO-Paket erheblich aktualisiert. Schauen wir uns ein Beispiel mit der KlasseFilesund der MethodereadAllBytesan. DiereadAllBytes-Methode akzeptiert einePath. Path-Klasse und kann als Upgrade derjava.io.File-Klasse mit einigen zusätzlichen Operationen betrachtet werden:

@Test
public void givenFilePath_whenUsingFilesReadAllBytes_thenFileData() {
   String expectedData = "Hello World from fileTest.txt!!!";

   Path path = Paths.get(getClass().getClassLoader()
     .getResource("fileTest.txt").toURI());
   byte[] fileBytes = Files.readAllBytes(path);
   String data = new String(fileBytes);

   Assert.assertEquals(expectedData, data.trim());
}

Diese Methode bietet auch eine bequeme Möglichkeit, den Inhalt einer Datei inString. einzulesen

5. Datei mit JDK8 lesen

JDK8 bietet die Methodelines()innerhalb der KlasseFiles. Es gibtStream von String-Elementen zurück.

Schauen wir uns ein Beispiel an, wie Daten in Bytes gelesen und mit dem UTF-8-Zeichensatz dekodiert werden:

@Test
public void givenFilePath_whenUsingFilesLines_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";

    Path path = Paths.get(getClass().getClassLoader()
      .getResource("fileTest.txt").toURI());

    Stream lines = Files.lines(path);
    String data = lines.collect(Collectors.joining("\n"));
    lines.close();

    Assert.assertEquals(expectedData, data.trim());
}

Wenn Sie Stream mit E / A-Kanälen wie Dateivorgängen verwenden, müssen Sie den Stream explizit mit der Methodeclose()chließen.

Wie wir sehen können, bietet dieFiles-API eine weitere einfache Möglichkeit, den Dateiinhalt inString. einzulesen

6. Datei lesen mit FileUtils

Eine weitere häufige Option ist die Verwendung der KlasseFileUtilsdes Paketscommons. Wir müssen die folgende Abhängigkeit hinzufügen:


    commons-io
    commons-io
    2.5

Stellen Sie sicher, dass Sie die neueste Abhängigkeitsversionhere überprüfen.

Der Code zum Lesen der Datei könnte folgendermaßen aussehen:

@Test
public void givenFileName_whenUsingFileUtils_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";

    ClassLoader classLoader = getClass().getClassLoader();
    File file = new File(classLoader.getResource("fileTest.txt").getFile());
    String data = FileUtils.readFileToString(file, "UTF-8");

    Assert.assertEquals(expectedData, data.trim());
}

Hier übergeben wir das ObjektFilean die MethodereadFileToString() der KlasseFileUtils. Diese Dienstprogrammklasse kann den Inhalt laden, ohne dass ein Boilerplate-Code geschrieben werden muss, um eineInputStream-Instanz zu erstellen und Daten zu lesen.

7. Datei mitIOUtils lesen

Eine weitere häufige Option ist die Verwendung derIOUtils -Skala descommons-Pakets. Sie müssen dieselbecommon-io-abhängigkeit hinzufügen, wie im vorherigenFileUtils-Beispiel erwähnt.

Schauen wir uns ein Anwendungsbeispiel an:

@Test
public void givenFileName_whenUsingIOUtils_thenFileData() {
    String expectedData = "This is a content of the file";

    FileInputStream fis = new FileInputStream("src/test/resources/fileToRead.txt");
    String data = IOUtils.toString(fis, "UTF-8");

    assertEquals(expectedData, data.trim());
}

Hier übergeben wir das ObjektFileInputStreaman die MethodetoString() der KlasseIOUtils. Diese Dienstprogrammklasse kann den Inhalt laden, ohne dass ein Boilerplate-Code geschrieben werden muss, um eineInputStream-Instanz zu erstellen und Daten zu lesen.

8. Lesen Sie den Inhalt von der URL

Um Inhalte von URLs zu lesen, verwenden wir in unserem Beispiel die URL "/" als:

@Test
public void givenURLName_whenUsingURL_thenFileData() {
    String expectedData = "example";

    URL urlObject = new URL("/");
    URLConnection urlConnection = urlObject.openConnection();
    InputStream inputStream = urlConnection.getInputStream();
    String data = readFromInputStream(inputStream);

    Assert.assertThat(data, containsString(expectedData));
}

Es gibt auch alternative Möglichkeiten, eine Verbindung zu einer URL herzustellen. Hier haben wir die im Standard-SDK verfügbaren KlassenURL undURLConnection verwendet.

9. Datei aus einem JAR lesen

Um eine Datei zu lesen, die sich in einer JAR-Datei befindet, benötigen wir eine JAR mit einer Datei darin. In unserem Beispiel lesen wir "LICENSE.txt" aus der Datei "hamcrest-library-1.3.jar":

@Test
public void givenFileName_whenUsingJarFile_thenFileData() {
    String expectedData = "BSD License";

    Class clazz = Matchers.class;
    InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt");
    String data = readFromInputStream(inputStream);

    Assert.assertThat(data, containsString(expectedData));
}

Hier möchten wirLICENSE.txt laden, die sich in der Hamcrest-Bibliothek befinden, also werden wir die KlasseMatcher’s verwenden, die beim Abrufen einer Ressource hilft. Dieselbe Datei kann auch mit dem Klassenladeprogramm geladen werden.

10. Fazit

In diesem Tutorial haben wir gesehen, wie Sie eine Datei von verschiedenen Speicherorten wie Klassenpfad-, URL- oder JAR-Dateien lesen.

Wir haben auch verschiedene Möglichkeiten gesehen, den Inhalt einer Datei zu lesen

Den Quellcode finden Sie in den folgendenGitHub repo.