2012-08-24 17 views
11

Sto utilizzando un costruttore BufferedReader per creare una nuova copia di uno BufferedReader esistente.Come posso creare una copia di BufferedReader?

BufferedReader buffReader = new BufferedReader(originalBuffReader); 

Il nuovo buffReader sta lavorando bene, ma quando lo faccio originalBuffReader.readLine() mi dà null. C'è un altro modo in cui posso creare un nuovo bufferReader senza influire sul mio originale BufferedReader.

Per prima cosa: sto ricevendo bufferReader come input per il mio metodo; e io non ho accesso alla fonte.

+0

Che cosa intendi esattamente con "copia di un BufferedReader"? Ti aspetti in qualche modo di poter leggere lo stesso stream due volte? Non è possibile. In effetti è una contraddizione in termini. – EJP

risposta

16

Qualsiasi altro modo posso fare una nuova bufferReader senza influire sul BufferReader oroginal

Non c'è modo dritto in avanti di risolverlo da solo la creazione di due BufferedReader s. (I due lettori consumeranno i dati dalla stessa fonte.) Dovrai aggiungere un altro livello di buffering all'origine, in modo che ogni lettore possa leggere il flusso in modo indipendente.

Ciò può essere ottenuto combinando TeeInputStream da Apache scorta e un PipedInputStream e PipedOutputStream come segue:

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

uscita:

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

Grazie aioobe per la tua risposta, in realtà sto ricevendo un buffer Reader come input per il mio metodo, quindi devo fare una copia usando quel bufferReader che non ha accesso al codice sorgente. – Sunil

+0

Quindi creerò un wrapper che avvolge il dato lettore bufferizzato, bufferizza le righe di lettura e distribuisce i lettori secondari, che leggono dal buffer. (A meno che tu non abbia la possibilità di drenare completamente i dati in una lista e usarla invece.) (Sono curioso, quale API ti dà solo una BufferedReader?) – aioobe

+1

BufferReader è riempito da qualche parte e passato attraverso un metodo come parametro e devo prenderlo da lì. – Sunil

2

Passando un'istanza BufferedReader nel costruttore per un nuovo BufferedReader non farà una copia del BufferedReader originale!

Ciò che si sta facendo è concatenare i due lettori, in altre parole, si sta eseguendo il buffering dell'istanza del lettore già memorizzata. Quando chiami readLine() su buffReader, chiamerà readLine() su originalBuffReader.

Date un'occhiata qui per maggiori dettagli del concatenamento di flussi: Chaining of Streams

0

Qui di seguito è un modo di prendere in considerazione la creazione di un nuovo BufferedReader fuori dal BufferedReader originale.

In sostanza, stiamo riversando il contenuto del lettore bufferizzato originale in una stringa e quindi ricreando un nuovo oggetto BufferedReader. Per poter rileggere l'originale BufferedReader una seconda volta è possibile contrassegnarlo e quindi dopo averlo letto, è possibile ripristinarlo.

Una cosa da tenere a mente è che potresti voler proteggere dagli attacchi DDOS, in cui un lettore bufferato molto grande può entrare e potresti voler evitare di leggere per sempre e riempire la memoria, puoi fondamentalmente rompere il loop dopo un certo punto o quando viene soddisfatta una determinata condizione.

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()))); 
Problemi correlati