2017-11-17 3 views
2

Ich möchte den Inhalt eines InputStream in eine String lesen:Sollen BufferedReader und InputStreamReader explizit geschlossen werden?

private String readToString(InputStream stream) { 
    return new BufferedReader(new InputStreamReader(stream)) 
      .lines().collect(Collectors.joining("\n")); 
} 

Der Strom kommt aus java.lang.Process.

Frage: Muss ich in diesem Fall einen der InputStream, InputStreamReader oder BufferedReader explizit schließen?

Nebenbei bemerkt: die verknüpfte Frage ist kein Duplikat, wie meine Frage nach WIE ist richtig, die Ströme nahe an, nicht wie der Stream in einen String zu lesen!

+0

Das [javadoc für 'linien'] (https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#lines--) scheint zu implizieren, dass der Stream nicht funktioniert. t wird automatisch geschlossen. – assylias

+0

nur eine Seite nicht Sie bekommen wahrscheinlich 'InputStream' aus einer' Datei' am wahrscheinlichsten. warum nicht 'File.lines' direkt verwenden? – Eugene

+2

Schließen Sie nichts. Wenn Sie den BufferedReader oder den InputStreamReader schließen, schließen sie implizit auch den InputStream. Aber diese Verantwortung sollte bei demjenigen liegen, der sie geöffnet hat (vorzugsweise in einem Versuch mit Ressourcen). Wenn Sie den gesamten Text in einen String lesen möchten, lesen Sie Zeile für Zeile nicht nur, um die Zeilen zu einer einzigen Zeichenfolge zusammenzufassen. Es gibt nichts besonderes an dem Newline-Zeichen, das bedeutet, dass die Datei so aufgeteilt werden muss. Lesen Sie stattdessen die gesamte Datei als Byte und konvertieren Sie sie mit der von Ihnen gewählten Codierung in Zeichen. – DodgyCodeException

Antwort

4

Sie nur die outer Wrapper schließen müssen, aber tun das nicht explizit so oder so - es gibt Anprobe mit-Ressource, die Ihnen das Leben leichter machen:

public String readToString(InputStream stream) { 

    try (InputStreamReader reader = new InputStreamReader(stream); 
      BufferedReader br = new BufferedReader(reader)) { 

     return br.lines().collect(Collectors.joining("\n")); 

    } catch (IOException e) { 
     e.printStackTrace(); 
     throw new RuntimeException(e); 
    } 
} 

Es gibt auch eine viel einfache Art und Weise, dass und Weise mehr klar zu machen:

Files.readAllLines(YourPath) 
+1

Ich bekomme den Inputstream von 'java.lang.process, also kann' Files' nicht verwendet werden. Aber Versuch-mit ist ok. – membersound

2

per meinem Kommentar, entweder die BufferedReader oder die Input Schließen wird die Input verursacht geschlossen werden. Ihre readToString Methode sollte den Stream nicht schließen. Dies liegt in der Verantwortung des Anrufers.

Die Begründung: -

Zunächst überlegen, wie Sie den Stream öffnen, bevor Sie readToString nennen. Eine sinnvolle Methode ist:

try (InputStream myStream = getInputStreamSomehow()) { 
    //... 
    String content = readToString(myStream); 
    //... 
} 

Der Stream wird am Ende des Blocks "try-with-resources" geschlossen.

Zweitens, Best Practices und Idiome berücksichtigen. Sehen Sie sich Java-API-Methoden an, die genau wie Ihre Methode den gesamten Inhalt eines Streams lesen. Beispielsweise aus der Java 9: ​​

Keines der obigen Verfahren schließt den Strom. Ebenso werden die Benutzer Ihrer readToString-Methode nicht erwarten, dass Sie ihren Stream schließen.

Verwandte Themen