2012-08-24 14 views
11

Estoy utilizando un constructor BufferedReader para hacer una nueva copia de un BufferedReader existente.¿Cómo puedo hacer una copia de un BufferedReader?

BufferedReader buffReader = new BufferedReader(originalBuffReader); 

El nuevo buffReader está trabajando muy bien, pero cuando lo hago me da originalBuffReader.readLine()null. ¿Hay alguna otra manera en que pueda hacer un nuevo bufferReader sin afectar mi BufferedReader original?

FYI: Estoy recibiendo bufferReader como una entrada a mi método; y no tengo acceso a la fuente.

+0

¿A qué se refieren exactamente por 'copy of a BufferedReader'? ¿Estás esperando de alguna manera poder leer el mismo flujo dos veces? No es posible. De hecho, es una contradicción en los términos. – EJP

Respuesta

16

Cualquier otra forma de que pueda hacer un nuevo bufferReader sin afectar mi BufferReader oroginal

No hay manera directa de resolverlo con sólo la creación de dos BufferedReader s. (Los dos lectores consumirán datos de la misma fuente). Tendrá que agregar otro nivel de almacenamiento en búfer en la fuente, para que cada lector pueda leer la secuencia de forma independiente.

Esto se puede lograr mediante la combinación de TeeInputStream de Apache Commons y una PipedInputStream y PipedOutputStream como sigue:

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

de salida:

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

Gracias por su respuesta, en realidad estoy obteniendo un bufferReader como una entrada a mi método, así que tengo que hacer una copia usando ese bufferReader no tiene acceso a la fuente. – Sunil

+0

Luego, crearía un contenedor que envuelve el lector almacenado, almacena en búfer las líneas de lectura y reparte lectores secundarios, que leen desde el búfer. (A menos que tenga la opción de drenar los datos completamente en una Lista y usar eso en su lugar.) (Tengo curiosidad, ¿qué API solo le da un BufferedReader?) – aioobe

+1

BufferReader se completa desde la fuente en algún lugar y se pasa a través de un método como un parámetro y tengo que tomarlo desde allí. – Sunil

2

Pasando en una instancia de BufferedReader en el constructor para una ¡El nuevo BufferedReader no hará una copia del BufferedReader original!

Lo que está haciendo allí es encadenar los dos lectores, en otras palabras, está almacenando en búfer la instancia de lector ya almacenada en el búfer. Cuando llame al readLine() en buffReader, llamará al readLine() en originalBuffReader.

Echa un vistazo aquí para más detalles del encadenamiento de flujos: Chaining of Streams

0

A continuación se muestra una forma de considerar la creación de un nuevo BufferedReader fuera del BufferedReader original.

Básicamente, estamos volcando el contenido del lector de búfer original en una cadena y luego recreando un nuevo objeto BufferedReader. Para poder volver a leer el BufferedReader original por segunda vez, puede marcarlo y luego, después de leerlo, puede restablecerlo.

Una cosa a tener en cuenta es que es posible que desee proteger mediante ataques DDOS, donde puede entrar un lector de gran tamaño y puede evitar leer para siempre y llenar la memoria, básicamente puede romper el bucle después de algún punto o cuando se cumple una determinada condición.

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()))); 
Cuestiones relacionadas