2012-08-24 19 views
11

BufferedReaderコンストラクタを使用して、既存のBufferedReaderの新しいコピーを作成しています。BufferedReaderのコピーを作成するにはどうすればよいですか?

BufferedReader buffReader = new BufferedReader(originalBuffReader); 

新しいbuffReaderが正常に動作しているが、私はoriginalBuffReader.readLine()を行うとき、それは私にnullを与えます。新しいbufferReaderを私のオリジナルのBufferedReaderに影響を与えずに作ることができる他の方法はありますか?

FYI:私のメソッドへの入力としてbufferReaderを取得しています。私はソースにアクセスできない。

+0

「BufferedReaderのコピー」とは、具体的にはどういう意味ですか?あなたは何とか同じストリームを2回読むことができると期待していますか?不可能です。実際、それは矛盾しています。 – EJP

答えて

16

私はちょうど2つのBufferedReader Sを作成することによって、それを解決するのないまっすぐ進む方法はありません私のoroginal BufferReader

に影響を与えることなく、新しいbufferReaderを作ることができ、他の方法。 (2人の読者は同じソースからのデータを消費するでしょう)。ソース上に別のレベルのバッファリングを追加する必要があるため、各読者は独立してストリームを読むことができます。

次のようにこれは、ApacheコモンズからTeeInputStreamを組み合わせ、PipedInputStreamによって、およびPipedOutputStream達成することができる。

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

出力:のコンストラクタにBufferedReaderインスタンスに渡す

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

ur返信のためのaioobeありがとう、実際には私のメソッドへの入力としてbufferReaderを取得していますので、そのbufferReaderを使用してコピーを作成してソースにアクセスする必要はありません。 – Sunil

+0

次に、指定されたバッファー付きリーダーをラップするラッパーを作成し、バッファーから読み取ったセカンダリー・リーダーをバッファーして読み取りラインをバッファーします。 (あなたは、リストの中にデータを完全に流して、それを代わりに使うという選択肢がない限り)(私は興味がありますが、どのAPIがあなたにBufferedReaderを与えるのですか?) – aioobe

+1

BufferReaderはどこかのソースから埋められ、パラメータとして私はそこからそれを取らなければならない。 – Sunil

2

を新しいBufferedReaderは元のBufferedReaderのコピーを作成しません!

ここでは、2つのリーダーを連鎖させています。つまり、すでにバッファーに入っているリーダーインスタンスをバッファしています。 buffReaderreadLine()と電話すると、originalBuffReaderreadLine()が呼び出されます。

は、ストリームの連鎖の詳細はこちらをご覧ください: Chaining of Streams

0

以下はオリジナルBufferedReaderのから新しいBufferedReaderの作成を検討する一つの方法です。

基本的に、元のバッファリングされたリーダーの内容を文字列にダンプし、新しいBufferedReaderオブジェクトを再作成します。 2度目に元の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()))); 
関連する問題