Eingabe / Ausgabe von Java-Dateien, die über den historischen Hintergrund verwendet werden können

Einführung

In der Vergangenheit war die Eingabe- / Ausgabeverarbeitung von Java als umständlich bekannt. Die Verarbeitung der Eingabe / Ausgabe von Dateien in Java war häufig das Ziel von Angriffen, als das Skript-Sprachcamp seine hohe "Produktivität" ansprach. Es wird gesagt, dass die Verarbeitung, die in wenigen Zeilen in einer Skriptsprache realisiert werden kann, in Java zu Dutzenden von Zeilen wird.

Die Zeit ist vergangen und die Situation hat sich mit dem 2011 in Java 7 eingeführten Paket "java.nio.file" (NIO2 File API) und der Try-with-Resources-Syntax erheblich verbessert. Jetzt kann sogar Java die Verarbeitung von Dateieingaben / -ausgaben mit der gleichen Codemenge wie die Skriptsprache realisieren.

In Artikeln, die nach "Eingabe / Ausgabe von Java-Dateien" suchen und ganz oben stehen, fällt jedoch nur unangemessener Code auf, der nur die API verwendet, bevor die oben genannten Verbesserungen eingeführt wurden. Daher möchte ich in diesem Artikel die einfachste Eingabe- / Ausgabeverarbeitung für Java-Dateien, die Anfänger derzeit kennen sollten, systematisch und präzise zusammenfassen, unabhängig vom historischen Hintergrund der Vergangenheit.

Vorausgesetztes Wissen

Darstellung des Weges

Die Schnittstelle java.nio.file.Path (Referenz: Javadoc wird verwendet, um den Pfad des Dateisystems darzustellen. /Path.html)) wird verwendet. Es gibt verschiedene Möglichkeiten, eine Pfadinstanz zu erstellen, aber in Wirklichkeit die Dienstprogrammklasse "java.nio.file.Paths" (Referenz: Javadoc Meistens generiert mit java / nio / file / Paths.html)).

Path path = Paths.get("items.csv");

Sie können die Pfadzeichenfolge entweder als relativen oder als absoluten Pfad angeben.

Path path = Paths.get("/etc/passwd");

In Anbetracht der Art der Portabilität von durch Pfade getrennten Zeichenfolgen ist es besser, diese Argumentmethode mit variabler Länge zu verwenden.

Path path = Paths.get("/etc", "passwd");

Ab Java 11 wurde zusätzlich zur Methode Paths.get (String) die Methode Path.of (String) eingeführt (Referenz: Javadoc. javase / 11 / docs / api / java.base / java / nio / file / Path.html # von (java.lang.String, java.lang.String ...))). Die Funktion ist dieselbe, aber diese ist konsistenter mit "List.of ()" "Map.of ()" usw., die ebenfalls in Java 11 eingeführt wurde, und ist natürlich.

Path path = Path.of("items.csv");

Grundlagen der Dateiverarbeitung

Die dateibezogene Verarbeitung erfolgt über die Schnittstelle "Path" und die Dienstprogrammklasse "java.nio.file.Files" (Referenz: Javadoc. Kombiniere nio / file / Files.html)). Zum Beispiel sieht es so aus.

List<String> lines = Files.readAllLines(Paths.get("items.csv"));

(Referenz) Beziehung zu java.io.File

Die Klasse, die eine Datei in Java darstellt, ist "java.io.File" (Referenz: Javadoc. )) Du könntest daran denken. Dies ist eine ältere Methode und kann durch die Funktionalität des Pakets java.nio.file ersetzt werden. Beachten Sie, dass Sie zwischen "Path # toFile ()" und "File # toPath ()" konvertieren können, wenn die alte API nur "java.io.File" anstelle von "java.nio.file.Path" akzeptiert.

Textdateien verarbeiten

Was ist eine Textdatei?

In diesem Artikel werden wir nicht auf die Details einer Textbinärdatei eingehen, sondern einfach Dateien vom Typ "String" aus Javas Sicht lesen und schreiben, die als Textdateien bezeichnet werden.

Lesen von Massentexten

Der einfachste Weg, Text zu lesen, ist die Methode "Files.readString (Path)". Diese Methode gibt den gesamten Inhalt der Datei als String zurück.

String content = Files.readString(Paths.get("items.csv"));

Sie müssen beim Lesen und Schreiben von Text auf den Zeichensatz achten. Der obige Code gibt keinen Zeichensatz an, daher wird der Standard-UTF-8 verwendet. Die Methode zur Angabe des Zeichensatzes ist unten dargestellt.

String content = Files.readString(Paths.get("items.csv"), StandardCharsets.UTF_8);
String content = Files.readString(Paths.get("items.csv"), Charset.forName("MS932"));

Nun, hier ist eine unglückliche Nachricht. Die oben beschriebene Methode "Files.readString (Path)" "Files.readString (Path, Charset)" ist nur in Java 11 und höher verfügbar. Hier ist eine andere Möglichkeit, wie Sie es von Java 7 aus verwenden können. Diese Methode gibt den Inhalt der Datei als Typ "List " zurück.

List<String> lines = Files.readAllLines(Paths.get("items.csv"), StandardCharsets.UTF_8);

Lesen Sie den unterteilten Text

Wenn die Dateigröße klein ist, können Sie sie alle wie oben beschrieben gleichzeitig lesen. Wenn Sie jedoch die Möglichkeit haben, Dateien zu verarbeiten, die größer als zehn oder Hunderte von Megabyte sind, sollten Sie sich daran erinnern, wie Sie hier mit "Stream " umgehen. Diese Methode hat eine bessere Leistung.

try (Stream<String> lines = Files.lines(Paths.get("items.csv"), StandardCharsets.UTF_8)) {
    lines.forEach(line -> System.out.println(line));
} catch (IOException e) {
    throw new UncheckedIOException(e);
}

Verwenden Sie bei Verwendung dieser Methode die Syntax "Try-with-Resources", um zu verhindern, dass das Schließen vergessen wird. Gleiches gilt für das Lesen und Schreiben anderer Unterteilungen. Weitere Informationen finden Sie unter Schrittweises Verständnis der Behandlung von Java-Ausnahmen.

Wenn Sie unterteilten Text lesen müssen, der nicht zeilenorientiert ist, wird "java.io.BufferedReader" von "Files.newBufferedReader (Path, Charset)" zurückgegeben (Referenz: Javadoc Verwenden Sie com / javase / jp / 8 / docs / api / java / io / BufferedReader.html)). Wenn Sie eine große JSON-Datei ohne Zeilenumbrüche lesen möchten, benötigen Sie diese Methode.

try (BufferedReader in = Files.newBufferedReader(Paths.get("items.csv"), StandardCharsets.UTF_8)) {
    for (int ch = 0; (ch = in.read()) > 0;) {
        System.out.print((char) ch);
    }
} catch (IOException e) {
    throw new UncheckedIOException(e);
}

Weitere Abstraktion in Kombination mit java.util.Scanner (Referenz: Javadoc) High API kann verwendet werden.

try (BufferedReader in = Files.newBufferedReader(Paths.get("items.csv"), StandardCharsets.UTF_8);
        Scanner sc = new Scanner(in)) {
    sc.useDelimiter("(,|\\n)");
    while (sc.hasNext()) {
        System.out.println(sc.next());
    }
} catch (IOException e) {
    throw new UncheckedIOException(e);
}

Massen-Textschreiben

Der einfachste Weg, Text zu schreiben, ist die Methode Files.writeString (Path, CharSequence, OpenOption ...). Diese Methode schreibt den gesamten Inhalt der angegebenen "CharSequence" in eine Datei. Außerdem sind "String" und "StringBuilder" eine Art "CharSequence" (Referenz: Javadoc. html)).

String content = "0-0\t0-1\t0-2\n1-0\t1-1\t1-2\n";
Files.writeString(Paths.get("items.tsv"), content);

Sie können es hinzufügen, indem Sie "OpenOption" einstellen.

String content = "0-0\t0-1\t0-2\n1-0\t1-1\t1-2\n";
Files.writeString(Paths.get("items.tsv"), content, StandardOpenOption.APPEND);

Sie können den Zeichensatz sowohl hier als auch beim Lesen angeben.

String content = "0-0\t0-1\t0-2\n1-0\t1-1\t1-2\n";
Files.writeString(Paths.get("items.tsv"), content, StandardCharsets.UTF_8);
String content = "0-0\t0-1\t0-2\n1-0\t1-1\t1-2\n";
Files.writeString(Paths.get("items.tsv"), content, Charset.forName("MS932"));

Hier ist eine weitere unglückliche Nachricht. Die obige Methode "Files.writeString (Pfad, CharSequence, OpenOption ...)" "Files.writeString (Pfad, CharSequence, Zeichensatz, OpenOption ...)" ist nur in Java 11 und höher verfügbar. Vorher können Sie nur die gleiche Methode anwenden wie beim Schreiben in kleinen Stücken.

Unterteiltes Schreiben von Text

Beim Schreiben von Text in kleinen Stücken wurde "java.io.BufferedWriter" von "Files.newBufferedWriter (Pfad, Zeichensatz, OpenOption ...)" zurückgegeben (Referenz: Javadoc /jp/8/docs/api/java/io/BufferedWriter.html)) wird verwendet.

List<String> lines = new ArrayList<String>();
...
try (BufferedWriter out = Files.newBufferedWriter(Paths.get("items.tsv"), StandardCharsets.UTF_8)) {
    for (String line : lines) {
        out.write(line);
        out.newLine();
    }
} catch (IOException e) {
    throw new UncheckedIOException(e);
}

Binärdateien verarbeiten

Was ist eine Binärdatei?

In diesem Artikel wird eine Datei, die aus Java-Sicht einfach als Byte-Zeichenfolge gelesen und geschrieben wird, als Binärdatei bezeichnet.

Bulk-Binärlesung

Der einfachste Weg, eine Binärdatei zu lesen, ist die Methode "Files.readBytes (Path)". Diese Methode gibt den gesamten Inhalt der Datei als "byte []" zurück.

byte[] content = Files.readAllBytes(Paths.get("selfie.jpg "));

Als Referenz wird unten die Methode zum Konvertieren von "byte []" in "String" oder "java.io.InputStream" gezeigt. Eine solche Konvertierung ist abhängig von der Benutzerfreundlichkeit der API erforderlich, an die die geladene Binärdatei übergeben wird.

byte[] content = Files.readAllBytes(Paths.get("items.csv"));
String contentAsString = new String(content, StandardCharsets.UTF_8);
byte[] content = Files.readAllBytes(Paths.get("selfie.jpg "));
InputStream in = new ByteArrayInputStream(content);

Unterteiltes binäres Lesen

Wie bei Text wird das Laden in großen Mengen für große Dateien nicht empfohlen. Stattdessen gibt die Methode "Files.newInputStream (Path, OpenOption ...)" "java.io.InputStream" zurück (Referenz: Javadoc Verwenden Sie /api/java/io/InputStream.html)). In Bezug auf den erworbenen java.io.InputStream gibt es mehr Fälle, in denen er von einer vorhandenen Bibliothek verarbeitet wird, als wenn er durch Drehen einer eigenen Schleife verarbeitet wird. Der folgende Code übergibt ihn beispielsweise an Apache POI.

try (InputStream in = Files.newInputStream(Paths.get("items.xlsx"))) {
    XSSFWorkbook book = new XSSFWorkbook(in);
    ...
} catch (IOException e) {
    throw new UncheckedIOException(e);
}

Bulk-Binärschreiben

Der einfachste Weg, eine Binärdatei zu schreiben, ist die Methode Files.write (Path, byte [], OpenOption ...).

byte[] content = ...;
Files.write(Paths.get("selfie.jpg "), content);

Unterteiltes binäres Schreiben

Beim Schreiben einer Binärdatei in kleinen Stücken wird "java.io.OutputStream" von "Files.newOutputStream (Path, OpenOption ...)" zurückgegeben (Referenz: Javadoc / 8 / docs / api / java / io / OutputStream.html))) wird verwendet. Es wird mehr Fälle geben, in denen die vorhandene Bibliothek dies ebenfalls behandelt, anstatt es selbst zu erledigen. Der folgende Code übergibt ihn beispielsweise an Apache POI.

Item item = ...;
try (OutputStream out = Files.newOutputStream(Paths.get("items.xlsx"))) {
    XSSFWorkbook book = new XSSFWorkbook();
    ...
    book.write(out);
} catch (IOException e) {
    throw new UncheckedIOException(e);
}

(Referenz) Alter komplizierter Schreibstil

Im Folgenden finden Sie ein Beispiel für Code, der in Zeiten üblich war, in denen es weder eine NIO2-Datei-API noch einen Versuch mit Ressourcen gab. Dies ist sicherlich eine Komplexität, die nicht beanstandet werden kann, selbst wenn sie vom Skript-Sprachcamp angegriffen wird. In Bezug auf den Teil, der ein mehrstufiger Try-Catch ist: "Wenn Sie" BufferedReader "schließen, wird auch der untere" InputStream "geschlossen. Wenn Sie" BufferedReader "jedoch nicht initialisieren, kann ein Ressourcenleck auftreten. Ich erinnere mich, dass es ein Argument wie "Es ist notwendig für ..." gab. Ich habe die Details vergessen und glaube nicht, dass ich mich mehr an sie erinnern muss.

String content = null;
InputStream is = null;
try {
    is = new FileInputStream("items.csv");
    BufferedReader br = null;
    try {
        br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = br.readLine()) != null) {
            sb.append(line);
            sb.append(System.lineSeparator());
        }
        content = sb.toString();
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        try {
            if (br != null) {
                br.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
} catch (IOException e) {
    new RuntimeException(e);
} finally {
    try {
        if (is != null) {
            is.close();
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

Was Sie mit dem obigen Code versuchen, können Sie jetzt wieder erreichen mit:

String content = Files.readString(Paths.get("items.csv"));

Recommended Posts

Eingabe / Ausgabe von Java-Dateien, die über den historischen Hintergrund verwendet werden können
Statisches Analysetool, das mit GitHub verwendet werden kann [Java-Version]
Zusammenfassung von ORM "uroboroSQL", das in Enterprise Java verwendet werden kann
[Android Studio] Beschreibung, die kontinuierlich in die SQLite-Datenbank eingegeben werden kann [Java]
[Java 8] Bis zur Konvertierung von Standardeingaben, die beim Codieren von Tests verwendet werden können, in eine Liste oder ein Array
Schreiben wir die Eingabe / Ausgabe von Java-Dateien mit NIO
Technologie-Auszug, mit dem EC-Sites in Java-Schulungen erstellt werden können
Organisieren Sie Methoden, die mit StringUtils verwendet werden können
Beispielprogramm für die Eingabe / Ausgabe von Java-Dateien (jdk1.8 oder höher)
Schreiben einer Klasse, die in Java bestellt werden kann Ein kleines Standard-Memo
Die Java 8 Stream-Verarbeitung kann bisher weggelassen werden!
Über die Sache, dass hidden_field wahnsinnig benutzt werden kann
Praktische Tastenkombinationen für Eclipse
Syntax- und Ausnahmebedingungen, die beim Vergleich mit null in Java verwendet werden können
[Java 8] Sortiermethode in alphabetischer Reihenfolge und Reihenfolge der Zeichenkettenlänge, die für Codierungstests verwendet werden kann
Erstellen Sie ein Seitensteuerelement, das mit RecyclerView verwendet werden kann
Erstellen Sie eine JAR-Datei, die auf Gradle ausgeführt werden kann
Firebase-Realtime-Datenbank für Android, die mit Kopie verwendet werden kann
Probleme, die leicht mit Java und JavaScript verwechselt werden können
Java (Super Beginner Edition), das in 180 Sekunden verstanden werden kann
Java 14 neue Funktionen, mit denen Code geschrieben werden kann
Gibt an, ob Optionen aufgrund unterschiedlicher Java-Versionen verwendet werden können
Referenznotiz / In-Memory-LDAP-Server, der in Java eingebettet werden kann
Beachten Sie, dass Systemeigenschaften einschließlich JAXBContext in Java11 nicht verwendet werden können
Kraftfertigkeiten, die jederzeit schnell eingesetzt werden können - Reflexion
SwiftUI-Ansicht, die in Kombination mit anderen Frameworks verwendet werden kann
[Spring Boot] Liste der Validierungsregeln, die in der Eigenschaftendatei für Fehlermeldungen verwendet werden können