2010-12-15 5 views
11

ich diesen Code in Java haben:eine Textzeile aus einem Eingangsstrom in Java Lesen Sie den Zeilenabschlusszeichen zu halten (s)

InputStreamReader isr = new InputStreamReader(getInputStream()); 
BufferedReader ir = new BufferedReader(isr); 
String line; 
while ((line = ir.readLine()) != null) { 
//do stuff with "line" 
} 

Wenn der Eingangsstrom enthält folgendes: „Hallo \ nhey \ ryo \ r \ Ngood-Tag“, dann würde Zeilenvariablen jeder auf Iteration folgenden werden:

  1. hallo
  2. hey
  3. yo
  4. gut da y

Ich möchte eine Zeile zu einer Zeit lesen, aber ich möchte das Line-Abschlusszeichen halten (s):

  1. Hallo \ n
  2. He \ r
  3. yo \ r \ n
  4. guter Tag

Wie kann ich das tun? Gibt es einen gebrauchsfertigen Unterricht, den ich benutzen kann?

-

Update:

Hier ist, was ich versuche zu tun ist, warum muss ich die End-of-Line-Zeichen halten (und warum das EOL-Zeichen unterschiedlich sein können).

Ich lese eine POST-Anfrage. Sie bestehen aus reinen Textnachrichten, wobei die Zeilen immer mit \ r \ n enden (nach der Standardspezifikation). Die POST-Anforderung kann jedoch Binärdaten enthalten, die Bytes enthalten können, die wie Beendigungszeichen für Java Reader-Objekte aussehen.

In meinem Beispiel wird ein Bild hochgeladen. Die Bilddaten werden in einer einzigen Zeile gesendet. Die Binärdaten des Bildes enthalten jedoch Bytes, die der READER als "\ n", "\ r" oder manchmal "\ r \ n" interpretieren würde, wenn diese beiden Bytes zufällig nebeneinander liegen.

Ich muss die POST-Anfrage Zeile für Zeile lesen, weil es so funktioniert. Ich könnte, ich könnte alles lesen und dann die ganze Sache analysieren. Aber das ist nicht effizient, besonders wenn eine große Datei (zB 1024 MiB) hochgeladen wird.

+0

Wenn Sie keine bessere Lösung finden können, können Sie Ihre 'readLine' mit' BufferedReader.read() 'in einer' while' Schleife implementieren. – pts

+0

Ich hatte gehofft, dass diese sehr einfache Sache bereits erledigt war, man hätte gedacht, dass sie es so gemacht haben könnte, dass die readLine() - Methode des BufferedReaders einen booleschen Wert akzeptiert - wenn wahr, würde sie auch die Zeilentrennzeichen und einschließen wenn es falsch ist, würde es sich so verhalten, wie es im Moment ist. – Mike

+0

Ist der besondere Endcharakter wichtig zu behalten? Weil das erste, was ich dachte, war nur ein '\ n' an die Zeile – TheLQ

Antwort

4

Wenn Sie eine HTTP POST-Anforderung lesen wollen, ich stark BufferedInputStream.read() vorschlagen (nicht BufferedReader!) Direkt (ohne readLine -artigen Zwischen Abstraktionen), manuell auf alle Details achten, einschließlich der Handhabung von CR und LF nach der HTTP-RFC.

Hier ist meine Antwort auf Ihre spezifischere Frage (wie man genau das implementiert readLine). Dies ist vielleicht nicht die schnellste Lösung, aber es ist Zeit, Komplexität optimal ist, und es funktioniert:

import java.io.BufferedReader; 
import java.io.IOException; 
public class LineReader { 
    private int i = -2; 
    private BufferedReader br; 
    public OriginalLineReader(BufferedReader br) { this.br = br; } 
    public String readLine() throws IOException { 
    if (i == -2) i = br.read(); 
    if (i < 0) return null; 
    StringBuilder sb = new StringBuilder(); 
    sb.append((char)i); 
    if (i != '\r' && i != '\n') { 
     while (0 <= (i = br.read()) && i != '\r' && i != '\n') { 
     sb.append((char)i); 
     } 
     if (i < 0) return sb.toString(); 
     sb.append((char)i); 
    } 
    if (i == '\r') { 
     i = br.read(); 
     if (i != '\n') return sb.toString(); 
     sb.append((char)'\n'); 
    } 
    i = -2; 
    return sb.toString(); 
    } 
} 

Sie werden nicht finden, eine solche readLine in Java gebaut. Es ist wahrscheinlich, dass Sie ähnliche, aber nicht genau übereinstimmende readLine s in einer .jar Datei von Drittanbietern finden. Meine Empfehlung ist nur, die oben genannte zu verwenden, wenn Sie diese Funktion wirklich benötigen.

+0

Das ist genau die Art von Code, den ich mir nicht selbst schreiben wollte, vielen Dank! Ich denke immer noch, dass es standardmäßig in Java hätte sein sollen. – Mike

+1

Als diese Java-APIs entwickelt wurden, war die plattformspezifische End-of-Line-Codierung noch wackeliger als jetzt. Sie versuchen, dich davon abzuhalten, sich mit \ n vs \ r vs \ r \ n zu beschäftigen, denn Gott weiß nur, was proprietäre * Nixes 1993 benutzten, indem er readLine und writeLine bereitstellte und intern damit umging. – Affe

+0

Affe: Ich denke, es gibt einen kleinen sachlichen Fehler in Ihrer Argumentation. Mein allgemeines Verständnis ist, dass alle Unix-Systeme immer "\ n" (was gleich "10" ist) als Leitungsabschluss haben. – pts