2012-08-24 17 views
11

Używam konstruktora BufferedReader do utworzenia nowej kopii istniejącego BufferedReader.Jak mogę utworzyć kopię BufferedReader?

BufferedReader buffReader = new BufferedReader(originalBuffReader); 

Nowa buffReader pracuje bez zarzutu, ale gdy robię originalBuffReader.readLine() daje mi null. Czy istnieje inny sposób, w jaki mogę utworzyć nowy bufferReader bez wpływu na mój oryginalny BufferedReader.

FYI: Otrzymuję bufferReader jako dane wejściowe do mojej metody; i nie mam dostępu do źródła.

+0

Co dokładnie masz na myśli przez "kopię BufferedReader"? Czy spodziewasz się, że będziesz w stanie przeczytać dwa razy ten sam strumień? To nie jest możliwe. W rzeczywistości jest to sprzeczność w terminach. – EJP

Odpowiedz

16

Każdy inny sposób można utworzyć nowy bufferReader bez wpływu na moją oroginal BufferReader

Nie ma prosty sposób go rozwiązać tylko przez utworzenie dwóch BufferedReader s. (Obaj czytelnicy będą zużywać dane z tego samego źródła.) Będziesz musiał dodać kolejny poziom buforowania na źródle, aby każdy czytelnik mógł czytać strumień niezależnie.

ten można osiągnąć przez połączenie TeeInputStream Apache Gmin i PipedInputStream i PipedOutputStream następująco:

import java.io.*; 
import org.apache.commons.io.input.TeeInputStream; 
class Test { 
    public static void main(String[] args) throws IOException { 

     // Create the source input stream. 
     InputStream is = new FileInputStream("filename.txt"); 

     // Create a piped input stream for one of the readers. 
     PipedInputStream in = new PipedInputStream(); 

     // Create a tee-splitter for the other reader. 
     TeeInputStream tee = new TeeInputStream(is, new PipedOutputStream(in)); 

     // Create the two buffered readers. 
     BufferedReader br1 = new BufferedReader(new InputStreamReader(tee)); 
     BufferedReader br2 = new BufferedReader(new InputStreamReader(in)); 

     // Do some interleaved reads from them. 
     System.out.println("One line from br1:"); 
     System.out.println(br1.readLine()); 
     System.out.println(); 

     System.out.println("Two lines from br2:"); 
     System.out.println(br2.readLine()); 
     System.out.println(br2.readLine()); 
     System.out.println(); 

     System.out.println("One line from br1:"); 
     System.out.println(br1.readLine()); 
     System.out.println(); 
    } 
} 

wyjściowa:

One line from br1: 
Line1: Lorem ipsum dolor sit amet,  <-- reading from start 

Two lines from br2: 
Line1: Lorem ipsum dolor sit amet,  <-- reading from start 
Line2: consectetur adipisicing elit, 

One line from br1: 
Line2: consectetur adipisicing elit, <-- resumes on line 2 
+0

Dzięki aioobe za odpowiedź ur, Właściwie otrzymuję bufferReader jako dane wejściowe do mojego metode, więc muszę zrobić kopię przy użyciu tego bufferReader nie mają dostępu do źródła. – Sunil

+0

Następnie utworzyłbym opakowanie, które otula dany buforowany czytnik, buforuje linie odczytu i rozdziela drugorzędne czytniki, które odczytują z bufora. (O ile nie masz możliwości całkowitego wyczyszczenia danych na liście i użyj ich zamiast tego.) (Ciekaw jestem, który interfejs API daje tylko bufor BufferedReader?) – aioobe

+1

BufferReader jest wypełniany ze źródła i przepuszczany przez metodę jako parametr i muszę go stąd pobrać. – Sunil

2

przechodzącą w przypadku BufferedReader w konstruktor nowy BufferedReader nie utworzy kopii oryginalnego BufferedReader!

To, co tu robisz, polega na łańcuchowaniu dwóch czytników, innymi słowy, buforujesz już zbuforowaną instancję czytnika. Po wywołaniu readLine() na buffReader, zadzwoni readLine() na originalBuffReader.

Spójrz tutaj po więcej szczegółów szeregowaniu strumieni: Chaining of Streams

0

Poniżej jest jeden sposób, aby rozważyć utworzenie nowego BufferedReader poza oryginalnym BufferedReader.

Zasadniczo wyrzucamy zawartość oryginalnego buforowanego czytnika do ciągu znaków, a następnie odtwarzamy nowy obiekt BufferedReader. Aby ponownie odczytać oryginalny bufor BufferedReader po raz drugi można go oznaczyć, a następnie po jego odczytaniu można go zresetować.

Trzeba pamiętać o tym, że możesz chcieć chronić się przez ataki DDoS, w których może wejść bardzo duży buforowany czytnik, a możesz chcieć uniknąć czytania na zawsze i zapełnić pamięć, możesz po prostu zepsuć pętla po pewnym punkcie lub gdy określony warunek zostanie spełniony.

final String originalBufferedReaderDump; 
originalBufferedReaderDump.mark(Integer.MAX_VALUE); 
for (String line; (line = originalBufferedReader.readLine()) != null; originalBufferedReaderDump+= line); 
originalBufferedReader.reset(); 
final BufferedReader copiedBufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(originalBufferedReaderDump.getBytes()))); 
Powiązane problemy