1789 Stimmen

Wie erstelle ich eine Java-Zeichenfolge aus dem Inhalt einer Datei?

Ich verwende das untenstehende Idiom schon seit einiger Zeit. Und es scheint das weit verbreitetste zu sein, zumindest auf den Seiten, die ich besucht habe.

Gibt es einen besseren/anderen Weg, um eine Datei in einen String in Java zu lesen?

private String readFile(String file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader (file));
    String line = null;
    StringBuilder stringBuilder = new StringBuilder();
    String ls = System.getProperty("line.separator");

    try {
        while((line = reader.readLine()) != null) {
            stringBuilder.append(line);
            stringBuilder.append(ls);
        }

        return stringBuilder.toString();
    } finally {
        reader.close();
    }
}

8 Stimmen

Kann mir jemand auf eine sehr einfache Weise erklären, was es mit dem NIO auf sich hat? Jedes Mal, wenn ich darüber lese, verliere ich mich in der x-ten Erwähnung eines Kanals :(

8 Stimmen

Bitte beachten Sie, dass nicht garantiert ist, dass der Zeilentrenner in der Datei derselbe ist wie der Zeilentrenner des Systems.

7 Stimmen

Der obige Code hat einen Fehler, bei dem ein zusätzliches Zeilenumbruchzeichen in der letzten Zeile hinzugefügt wird. Es sollte etwas Ähnliches wie folgt sein: if ( (line = reader.readLine()) != null) { stringBuilder.append( line ); } while ( (line = reader.readLine()) != null) { stringBuilder.append( ls ); stringBuilder.append( line ); }

3voto

barjak Punkte 10134

Dieses verwendet die Methode RandomAccessFile.readFully, die anscheinend seit JDK 1.0 verfügbar ist!

public static String readFileContent(String filename, Charset charset) throws IOException {
    RandomAccessFile raf = null;
    try {
        raf = new RandomAccessFile(filename, "r");
        byte[] buffer = new byte[(int)raf.length()];
        raf.readFully(buffer);
        return new String(buffer, charset);
    } finally {
        closeStream(raf);
    }
} 

private static void closeStream(Closeable c) {
    if (c != null) {
        try {
            c.close();
        } catch (IOException ex) {
            // do nothing
        }
    }
}

2voto

OscarRyz Punkte 189898

Außerdem, wenn Ihre Datei zufällig in einem Jar liegt, können Sie auch dies verwenden:

public String fromFileInJar(String path) {
    try ( Scanner scanner 
            = new Scanner(getClass().getResourceAsStream(path))) {
        return scanner.useDelimiter("\\A").next();
    }
}

Der Pfad sollte mit / beginnen, zum Beispiel, wenn Ihr Jar ist

my.jar/com/some/thing/a.txt

Dann möchten Sie es so aufrufen:

String myTxt = fromFileInJar("/com/com/thing/a.txt");

2voto

Malcolm Boekhoff Punkte 912

In einer Zeile (Java 8), vorausgesetzt, Sie haben einen Reader:

String sMessage = String.join("\n", reader.lines().collect(Collectors.toList()));

2voto

Haakon Løtveit Punkte 898

Nachdem ich nach Scanner gesucht habe, denke ich, dass die Scanner-Lösung auch aufgelistet werden sollte. Am einfachsten zu lesen geht es so:

public String fileToString(File file, Charset charset) {
  Scanner fileReader = new Scanner(file, charset);
  fileReader.useDelimiter("\\Z"); // \Z bedeutet EOF.
  String out = fileReader.next();
  fileReader.close();
  return out;
}

Wenn Sie Java 7 oder neuer verwenden (und das sollten Sie wirklich), sollten Sie erwägen, try-with-resources zu verwenden, um den Code einfacher zu lesen. Kein "dot-close"-Zeug mehr überall herumliegen. Aber das ist größtenteils eine stilistische Wahl, denke ich.

Ich poste das hauptsächlich aus Gründen der Vollständigkeit, denn wenn Sie das häufig tun müssen, sollten in java.nio.file.Files Dinge sein, die die Aufgabe besser erledigen.

Mein Vorschlag wäre, Files#readAllBytes(Path) zu verwenden, um alle Bytes zu erfassen, und sie an String(byte[] Charset) zu übergeben, um einen String daraus zu erhalten, dem Sie vertrauen können. Zeichensätze werden Ihnen während Ihres Lebens Unannehmlichkeiten bereiten, also seien Sie jetzt vorsichtig bei diesen Dingen.

Andere haben bereits Code und so weiter gegeben, und ich möchte ihren Ruhm nicht stehlen. ;)

2voto

Ajk Punkte 499

Ich kann noch keine Kommentare zu anderen Einträgen abgeben, also lasse ich es hier.

Eine der besten Antworten hier (https://stackoverflow.com/a/326448/1521167):

private String readFile(String pathname) throws IOException {

File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
String lineSeparator = System.getProperty("line.separator");

try {
    while(scanner.hasNextLine()) {        
        fileContents.append(scanner.nextLine() + lineSeparator);
    }
    return fileContents.toString();
} finally {
    scanner.close();
}
}

hat immer noch einen Fehler. Es fügt immer ein neues Zeilenzeichen am Ende des Strings ein, was zu seltsamen Fehlern führen kann. Mein Vorschlag ist es zu ändern zu:

    private String readFile(String pathname) throws IOException {
    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int) file.length());
    Scanner scanner = new Scanner(new BufferedReader(new FileReader(file)));
    String lineSeparator = System.getProperty("line.separator");

    try {
        if (scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine());
        }
        while (scanner.hasNextLine()) {
            fileContents.append(lineSeparator + scanner.nextLine());
        }
        return fileContents.toString();
    } finally {
        scanner.close();
    }
}

0 Stimmen

Im ersten Fall fügen Sie möglicherweise am Ende eine zusätzliche Zeilenumbruch hinzu. Im zweiten Fall lassen Sie möglicherweise einen aus. Daher sind beide gleich falsch. Siehe diesen Artikel.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X