BufferedReader中有什么标记和重置?

时间:2011-11-23 09:47:07

标签: java stream bufferedreader

我想知道mark()的{​​{1}}和reset()方法是什么?我该如何使用它们?我读过Javadoc,但作为初学者,我无法理解它。

6 个答案:

答案 0 :(得分:14)

流的markreset方法提供了一种在流中向后跳转并重新读取数据的方法。

当你在mark()上拨打BufferedReader时,它会开始将你从该点读取的数据保存在其内部缓冲区中。当您调用reset()时,它将跳回到流的标记位置,因此内存缓冲区将满足下一个read()。当您阅读该缓冲区的末尾时,它将无缝地返回读取新数据。 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已支持mark和{{1} }} 他们自己!从内存中数据源读取的流通常支持resetmark,因为它们已经拥有内存中的所有数据,因此它们很容易读取再次。从文件或管道或网络套接字读取的流自然不支持resetmark,但您始终可以将该功能包装到reset或{{1 }}

答案 1 :(得分:9)

mark()标记流中的特定点,reset()将流重置为最新标记。这些方法提供book-marking功能,允许您在流中预读以检查即将到来的数据。

从此documentation:

  

标记()方法标记输入中可以“重置”流的位置   调用reset()方法。参数readLimit是数字   在之前设置标记后可以从流中读取的字符   商标无效。例如,如果使用read调用mark()   限制为10,然后从流中读取11个数据字符   在调用reset()方法之前,那么标记是无效的   流对象实例不需要记住标记。注意   可以通过此方法记住的字符数   大于内部读缓冲区的大小。它也不是   依赖于支持标记/重置的从属流   功能。

答案 2 :(得分:6)

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

答案 3 :(得分:1)

读者界面让你回来,你可以阅读。另一方面,BufferedReader创建一个缓冲区,因此您可以在读取时返回一点。这就是这些方法的用途。

使用mark()方法,您可以在某个位置放置“标记”,然后您可以继续阅读。一旦你意识到你想要返回标记的位置,你就可以使用reset()。从那时起,您再次阅读相同的值。你可以将它用于任何你想要的东西。

答案 4 :(得分:1)

想象一下,你在BufferReader =“123456789”中有以下字符,如果你在相对于'5'字符的位置4标记,那么重置你的BufferReader,你最终会得到12345。

答案 5 :(得分:0)

这是一个例子。

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是一个很好的参考。