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 ); }

73voto

finnw Punkte 46519

Guava hat eine Methode, die derjenigen von Commons IOUtils ähnelt, die Willi aus Rohr erwähnt hat:

import com.google.common.base.Charsets;
import com.google.common.io.Files;

// ...

String text = Files.toString(new File(path), Charsets.UTF_8);

Bearbeitung von PiggyPiglet
Files#toString ist veraltet und wird im Oktober 2019 entfernt. Verwenden Sie stattdessen Files.asCharSource(new File(path), StandardCharsets.UTF_8).read();

Bearbeitung von Oscar Reyes

Dies ist der (vereinfachte) zugrunde liegende Code in der zitierten Bibliothek:

InputStream in = new FileInputStream(file);
byte[] b  = new byte[file.length()];
int len = b.length;
int total = 0;

while (total < len) {
  int result = in.read(b, total, len - total);
  if (result == -1) {
    break;
  }
  total += result;
}

return new String( b , Charsets.UTF_8 );

Bearbeitung (von Jonik): Das obige stimmt nicht mit dem Quellcode aktueller Guava-Versionen überein. Für den aktuellen Quellcode siehe die Klassen Files, CharStreams, ByteSource und CharSource im Paket com.google.common.io.

0 Stimmen

Dieser Code hat Casting von long nach int, was bei großen Dateien zu unerwartetem Verhalten führen könnte. Hat zusätzliche Leerzeichen und wo schließt du den InputStream?

0 Stimmen

@M-T-A: Der Stream ist geschlossen, beachte die Verwendung von Closer in CharSource. Der Code in der Antwort ist nicht der tatsächliche, aktuelle Guava-Quellcode.

61voto

user590444 Punkte 4104
import java.nio.file.Files;

.......

 String readFile(String filename) {
            File f = new File(filename);
            try {
                byte[] bytes = Files.readAllBytes(f.toPath());
                return new String(bytes,"UTF-8");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
    }

14 Stimmen

Oder new String(Files.readAllBytes(Paths.get(filename))); :-)

52voto

Andrei N Punkte 4486

Wenn Sie eine Zeichenfolgenverarbeitung (parallele Verarbeitung) benötigen, verfügt Java 8 über die großartige Stream-API.

String result = Files.lines(Paths.get("file.txt"))
                    .parallel() // für parallele Verarbeitung
                    .map(String::trim) // um die Zeile zu ändern
                    .filter(line -> line.length() > 2) // um einige Zeilen nach einem Prädikat zu filtern
                    .collect(Collectors.joining()); // um Zeilen zu verbinden

Weitere Beispiele finden Sie in den JDK-Beispielen sample/lambda/BulkDataOperations, die von der Oracle Java SE 8 Download-Seite heruntergeladen werden können.

Ein weiteres Einzeilerbeispiel

String out = String.join("\n", Files.readAllLines(Paths.get("file.txt")));

1 Stimmen

Der von Files.lines(Paths.get("file.txt")) zurückgegebene Stream wird nicht geschlossen und führt zu einem Ressourcenleck. Sie sollten diesen in einem try-with-resources Block einwickeln.

51voto

Jon Skeet Punkte 1325502

Dieser Code wird Zeilenumbrüche normalisieren, was möglicherweise nicht das ist, was du wirklich tun möchtest.

Hier ist eine Alternative, die das nicht macht und (meiner Meinung nach) einfacher zu verstehen ist als der NIO-Code (obwohl er immer noch java.nio.charset.Charset verwendet):

public static String readFile(String file, String csName)
            throws IOException {
    Charset cs = Charset.forName(csName);
    return readFile(file, cs);
}

public static String readFile(String file, Charset cs)
            throws IOException {
    // Es ist wirklich nicht notwendig, den BufferedReader/InputStreamReader zu schließen
    // da sie nur den Stream umschließen
    FileInputStream stream = new FileInputStream(file);
    try {
        Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[8192];
        int read;
        while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
            builder.append(buffer, 0, read);
        }
        return builder.toString();
    } finally {
        // Möglicher Fehler hier: Wenn dies eine IOException wirft,
        // wird sie alle anderen maskieren. Normalerweise würde ich eine Hilfsmethode verwenden, die Ausnahmen protokolliert und verschluckt
        stream.close();
    }        
}

1 Stimmen

Verzeihen Sie mir, dass ich einen so alten Kommentar wiederbelebt habe, aber meinten Sie, einen String-Objekt namens "file" zu übergeben, oder sollte es stattdessen ein File-Objekt sein?

1 Stimmen

Tolle Antwort. +1. Aber diese Antwort ist 12 Jahre alt. Java hat jetzt try-with-resources.

33voto

Yash Punkte 8318

Alle möglichen Möglichkeiten zum Lesen der Datei als String von Datenträger oder Netzwerk gesammelt.

  • Guava: Google unter Verwendung der Klassen Resources, Files

    static Charset charset = com.google.common.base.Charsets.UTF_8;
    public static String guava_ServerFile( URL url ) throws IOException {
        return Resources.toString( url, charset );
    }
    public static String guava_DiskFile( File file ) throws IOException {
        return Files.toString( file, charset );
    }

  • APACHE - COMMONS IO unter Verwendung der Klassen IOUtils, FileUtils

    static Charset encoding = org.apache.commons.io.Charsets.UTF_8;
    public static String commons_IOUtils( URL url ) throws IOException {
        java.io.InputStream in = url.openStream();
        try {
            return IOUtils.toString( in, encoding );
        } finally {
            IOUtils.closeQuietly(in);
        }
    }
    public static String commons_FileUtils( File file ) throws IOException {
        return FileUtils.readFileToString( file, encoding );
        /*List lines = FileUtils.readLines( fileName, encoding );
        return lines.stream().collect( Collectors.joining("\n") );*/
    }

  • Java 8 BufferReader unter Verwendung der Stream API

    public static String streamURL_Buffer( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        BufferedReader reader = new BufferedReader( new InputStreamReader( source ) );
        //List lines = reader.lines().collect( Collectors.toList() );
        return reader.lines().collect( Collectors.joining( System.lineSeparator() ) );
    }
    public static String streamFile_Buffer( File file ) throws IOException {
        BufferedReader reader = new BufferedReader( new FileReader( file ) );
        return reader.lines().collect(Collectors.joining(System.lineSeparator()));
    }

  • Scanner-Klasse mit Regex \A, die den Anfang der Eingabe matcht.

    static String charsetName = java.nio.charset.StandardCharsets.UTF_8.toString();
    public static String streamURL_Scanner( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        Scanner scanner = new Scanner(source, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }
    public static String streamFile_Scanner( File file ) throws IOException {
        Scanner scanner = new Scanner(file, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }

  • Java 7 (java.nio.file.Files.readAllBytes)

    public static String getDiskFile_Java7( File file ) throws IOException {
        byte[] readAllBytes = java.nio.file.Files.readAllBytes(Paths.get( file.getAbsolutePath() ));
        return new String( readAllBytes );
    }

  • BufferedReader unter Verwendung von InputStreamReader.

    public static String getDiskFile_Lines( File file ) throws IOException {
        StringBuffer text = new StringBuffer();
        FileInputStream fileStream = new FileInputStream( file );
        BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );
        for ( String line; (line = br.readLine()) != null; )
            text.append( line + System.lineSeparator() );
        return text.toString();
    }

Beispiel mit Hauptmethode zum Zugriff auf die obigen Methoden.

public static void main(String[] args) throws IOException {
    String fileName = "E:/parametarisation.csv";
    File file = new File( fileName );

    String fileStream = commons_FileUtils( file );
            // guava_DiskFile( file );
            // streamFile_Buffer( file );
            // getDiskFile_Java7( file );
            // getDiskFile_Lines( file );
    System.out.println( " Datei über Datenträger: \n"+ fileStream );

    try {
        String src = "https://code.jquery.com/jquery-3.2.1.js";
        URL url = new URL( src );

        String urlStream = commons_IOUtils( url );
                // guava_ServerFile( url );
                // streamURL_Scanner( url );
                // streamURL_Buffer( url );
        System.out.println( " Datei über Netzwerk: \n"+ urlStream );
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

@see

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