BufferedReader
のmark()
およびreset()
メソッドとは何ですか?それらをどのように使用しますか?私はJavadocを読みましたが、初心者には理解できませんでした。
ストリームのmark
メソッドとreset
メソッドは、ストリーム内を逆方向にジャンプしてデータを再度読み取る方法を提供します。
BufferedReader
でmark()
を呼び出すと、そのポイントから読み取ったデータを内部バッファーに転送し続けます。 reset()
を呼び出すと、ストリームのマークされた位置にジャンプして戻るので、次のread()
sはメモリ内バッファーによって満たされます。そのバッファーの終わりを超えて読み取ると、シームレスに新しいデータの読み取りに戻ります。 BufferedInputStream
も同じように機能します。
mark
へのintパラメータは、後方に移動できるようにする最大文字数(BufferedReader
の場合)またはバイト数(BufferedInputStream
の場合)を伝えます。マークされた位置を超えて多くのデータを読み取ると、マークが「無効」になり、reset()
の呼び出しが例外で失敗します。
小さな例:
_BufferedReader r = new BufferedReader(new StringReader(
"Happy Birthday to You!\n" +
"Happy Birthday, dear " + System.getProperty("user.name") + "!"));
r.mark(1000); // save the data we are about to read
System.out.println(r.readLine()); // read the first line
r.reset(); // jump back to the marked position
r.mark(1000); // start saving the data again
System.out.println(r.readLine()); // read the first line again
System.out.println(r.readLine()); // read the second line
r.reset(); // jump back to the marked position
System.out.println(r.readLine()); // read the first line one final time
_
その例では、StringReader
をBufferedReader
でラップしてreadLine()
メソッドを取得しましたが、StringReader
sはすでにmark
およびreset
を独自にサポートしています! in-memoryデータソースから読み取るストリームは、通常、mark
とreset
自体をサポートしています。これは、すべてのデータがメモリに既にあるため、簡単に再度読み取ることができるためです。ファイル、パイプ、またはネットワークソケットから読み取るストリームは、自然にmark
とreset
をサポートしていませんが、BufferedInputStream
またはBufferedReader
でラップすることにより、いつでもその機能を任意のストリームに追加できます。
mark()
はストリーム内の特定のポイントをマークし、reset()
はストリームを最新のマークにリセットします。これらのメソッドはbook-marking
ストリームで先読みして、次のデータを検査できる機能。
これから documentation:
mark()メソッドは、reset()メソッドを呼び出して、ストリームを「リセット」できる入力内の位置をマークします。パラメータreadLimitは、マークを設定した後、マークが無効になる前にストリームから読み取ることができる文字数です。たとえば、読み取り制限が10でmark()が呼び出された場合、reset()メソッドが呼び出される前にストリームから11文字のデータが読み取られると、マークは無効になり、ストリームオブジェクトインスタンスは必要ありません。マークを覚えておいてください。このメソッドで記憶できる文字数は、内部読み取りバッファーのサイズよりも大きくなる可能性があることに注意してください。また、マーク/リセット機能をサポートする従属ストリームには依存しません。
Reader::mark(int readLimit)
ドキュメントは言う:
このリーダーのマーク位置を設定します。パラメータreadLimitは、マークが無効になるまでに読み取ることができる文字数を示します。 reset()を呼び出すと、readLimitを超えていない場合、リーダーがマークされた位置に再配置されます。
例:
import Java.io.*;
import static Java.lang.System.out;
public class App {
public static final String TEST_STR = "Line 1\nLine 2\nLine 3\nLine 4\n";
public static void main(String[] args) {
try (BufferedReader in = new BufferedReader(new StringReader(TEST_STR))) {
// first check if this Reader support mark operation
if (in.markSupported()) {
out.println(in.readLine());
in.mark(0); // mark 'Line 2'
out.println(in.readLine());
out.println(in.readLine());
in.reset(); // reset 'Line 2'
out.println(in.readLine());
in.reset(); // reset 'Line 2'
out.println(in.readLine());
in.mark(0); // mark 'Line 3'
out.println(in.readLine());
in.reset(); // reset 'Line 3'
out.println(in.readLine());
out.println(in.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
出力:
Line 1
Line 2
Line 3
Line 2
Line 2
Line 3
Line 3
Line 4
BufferReader = "123456789"に次の文字があると想像してください。'5 '文字に対して4番目の位置にマークを付けてから、BufferReaderをリセットすると、12345になります。
リーダーインターフェースはnotを使用して戻ります。読むことができます。一方、BufferedReaderはバッファを作成するため、読み取り時にビットを返すことができます。そして、これがそれらのメソッドの目的です。
Mark()メソッドを使用すると、「マーカー」を特定の位置に配置して、次に読むことができます。マークされた位置を返したいことがわかったら、reset()を使用します。その時点から、同じ値を再度読み取ります。何にでも使えます。
ここに例があります。
int bufferSize = 4;
int readLimit = 4
ByteArrayInputStream byteInputStream = new ByteArrayInputStream("123456789abcdef".getBytes());
try(BufferedInputStream bufferedInputStream = new BufferedInputStream(byteInputStream, bufferSize)) {
bufferedInputStream.mark(readLimit);
System.out.print((char) bufferedInputStream.read());//byte1
System.out.print((char) bufferedInputStream.read());//byte2
System.out.print((char) bufferedInputStream.read());//byte3
System.out.print((char) bufferedInputStream.read());//byte4
bufferedInputStream.reset();
System.out.print((char) bufferedInputStream.read());//byte5
// Using this next reset() instead of the first one will throw an exception
// bufferedInputStream.reset();
System.out.print((char) bufferedInputStream.read());
System.out.print((char) bufferedInputStream.read());
System.out.print((char) bufferedInputStream.read());
}
出力:12341234
readLimit
の目的のために、 here's は参考文献です。