2013-07-30 8 views
5

Jest to kod:Pierwszy znak jest odcięta kiedy BufferedReader służy

File file = new File("Hello.txt"); 
file.createNewFile(); 
FileWriter write = new FileWriter(file); 
BufferedWriter bufWrite = new BufferedWriter(write); 
bufWrite.write("HelloWorld"); 
bufWrite.flush(); 
bufWrite.close(); 

FileReader read = new FileReader(file); 
BufferedReader bufRead = new BufferedReader(read); 
while(bufRead.read()!=-1){ 
System.out.println(bufRead.readLine()); 
} 
bufRead.close(); 

Tutaj wyjście jest elloWorld. "Nie ma go. Dlaczego tak jest? Nie jestem pewien, czy robię coś złego tutaj!

Odpowiedz

8

Jest to zaskakujące częste pytanie.

Kiedy robisz

bufRead.read() 

właściwie odczytać znak, że nie umieścić go z powrotem i niech ją ponownie przeczytać później.

Najprostszym rozwiązaniem jest nie robienie tego.

File file = new File("Hello.txt"); 
try (PrintWriter pw = new PrintWriter(new FileWriter(file))) { 
    pw.println("HelloWorld"); // should have a new line 
} 

try (BufferedReader br = new BufferedReader(new FileReader(file))) { 
    for (String line; (line = br.readLine()) != null;) { 
     System.out.println(line); 
    } 
} 
+3

+1: Wypróbuj zasoby i zachowaj zakres "linii" tam, gdzie należy. Tak to się robi. –

3

To ma bardzo prostego powodu: Linia

while(bufRead.read()!=-1){ 

zużywa jeden znak ze strumienia wejściowego. Od the documentation:

Reads a single character. This method will block until a character is available, an I/O error occurs, or the end of the stream is reached. 
+0

tak jak uzyskać znak, który został już czytać. –

1

bufRead.read() odczytuje pierwszy char.

Zamiast tego wykonaj bufRead.ready().

+0

Nie. 'Ready()' mówi, czy istnieją dane do odczytu * bez blokowania *, co nie jest tym samym, co dane do odczytania. OP musi tylko wywołać "readLine()" tutaj. – EJP

9

Spójrz na swojej pętli:

while(bufRead.read()!=-1){ 
System.out.println(bufRead.readLine()); 
} 

Używasz read w pętli - co pochłonie pierwszy znak następnej linii.

Należy użyć:

String line; 
while ((line = bufRead.readLine()) != null) { 
    System.out.println(line); 
} 
+0

Ups :-) Wielkie dzięki! – Mercenary

+0

Proponuję użyć pętli for, aby zadeklarować 'String line' jak w mojej odpowiedzi. –

+3

@PeterLawrey: Widzę atrakcję pod względem zmniejszania zasięgu, ale wolę pętlę 'while' w ogóle, obawiam się. Czuję się dla mnie trochę mniej obcy. –

1

Już odczytać znak na

while(bufRead.read()!=-1) 

Jeśli istnieje więcej niż jeden linie znikną to będzie pierwszy znak każdej linii!

więc używać

String line; 
while ((line = bufRead.readLine()) != null) { 
    System.out.println(line); 
} 

Zobacz read()readLine()