2012-08-24 5 views
11

BufferedReader 생성자를 사용하여 기존 BufferedReader의 새 복사본을 만듭니다. BufferedReader의 복사본을 만들려면 어떻게해야합니까?

BufferedReader buffReader = new BufferedReader(originalBuffReader); 

새로운 buffReader

는 잘 작동하지만, 내가 originalBuffReader.readLine()을 할 때 나에게 null을 제공합니다. 원래 BufferedReader에 영향을주지 않고 새로 만들 수있는 다른 방법이 있나요? bufferReader

FYI : bufferReader를 입력으로 사용하고 있습니다. 나는 출처에 접근 할 수 없다.

+0

'BufferedReader 사본'이란 정확히 무엇을 의미합니까? 어떻게 든 두 번 같은 스트림을 읽을 수있을 것으로 기대하십니까? 그것은 불가능합니다. 사실 그것은 모순입니다. – EJP

답변

16

다른 방법으로 내 oroginal BufferReader

BufferedReader의를 작성하여 그것을 해결의 더 똑 바른 앞으로 방법이 없습니다에 영향을주지 않고 새로운 bufferReader을 만들 수 있습니다. (두 독자는 동일한 소스의 데이터를 소비합니다.) 소스에 버퍼링 수준을 추가해야 각 독자가 스트림을 독립적으로 읽을 수 있습니다.

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

출력

:

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

감사를위한 aioobe 주셔서 감사합니다, 사실 나는 내 methode에 대한 입력으로 bufferReader를 얻고 있습니다. 그래서 bufferReader를 사용하여 복사본을 만들어 소스에 액세스 할 필요가 없습니다. – Sunil

+0

그러면 주어진 버퍼링 된 판독기를 래핑하는 래퍼를 작성하고, 버퍼를 읽는 보조 판독기를 제외하고 읽기 라인을 버퍼링하고 처리합니다. (목록 에 데이터를 완전히 배수하고 그 대신에 사용할 수있는 옵션이 아니라면) (내가 궁금한 점은 어떤 API가 BufferedReader를 제공 하는가?) – aioobe

+1

BufferReader가 소스에서 채워져 메서드를 통과했습니다. 매개 변수로 사용하고 거기에서 가져와야합니다. – Sunil

2

는 생성자에 BufferedReader 인스턴스에 전달 다음

아파치 공용 TeeInputStreamPipedInputStreamPipedOutputStream을 조합함으로써 달성 될 수있다 새로운 BufferedReader은 원본 BufferedReader의 복사본을 만들지 않습니다!

두 개의 리더를 체인으로 묶는 것, 즉 이미 버퍼 된 리더 인스턴스를 버퍼링하고있는 중입니다. buffReaderreadLine()으로 전화하면 에 readLine()이 표시됩니다.

는 스트림의 체인의 자세한 내용은 여기를보세요 : Chaining of Streams

0

아래는 원래의 BufferedReader에서 새로운 BufferedReader로를 만드는 것이 한 가지 방법입니다.

기본적으로 원래 버퍼링 된 판독기의 내용을 문자열로 덤프 한 다음 새 BufferedReader 개체를 다시 작성합니다. 두 번째로 원래의 BufferedReader를 다시 읽을 수있게하려면 해당 버퍼를 읽은 다음 다시 설정할 수 있습니다.

유념해야 할 점 중 하나는 DDoS 공격으로 보호하기를 원할 것입니다. 매우 큰 버퍼링 된 리더가 들어올 수 있으며 언제 까지나 읽지 않고 메모리를 채우고 싶을 수도 있습니다. 어떤 시점 이후 또는 특정 조건이 충족 될 때 반복하십시오.

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()))); 
관련 문제