Java BufferedReader中的标记和重置是什么?
我想知道Java BufferedReader中的标记和重置是什么?,java,stream,bufferedreader,Java,Stream,Bufferedreader,我想知道BufferedReader的mark()和reset()方法是什么?我如何使用它们?我读过Javadoc,但作为一名初学者,我无法理解它。读者界面不允许您返回,您可以直接阅读。另一方面,BufferedReader创建了一个缓冲区,因此您可以在读取时返回一个位。这就是这些方法的用途 使用mark()方法,您可以在某个位置放置一个“标记”,然后继续阅读。一旦您意识到要返回标记的位置,就可以使用reset()进行返回。从这一点上,你再次读取相同的值。您可以将其用于任何需要的用途。假设您在B
BufferedReader
的mark()
和reset()
方法是什么?我如何使用它们?我读过Javadoc,但作为一名初学者,我无法理解它。读者界面不允许您返回,您可以直接阅读。另一方面,BufferedReader创建了一个缓冲区,因此您可以在读取时返回一个位。这就是这些方法的用途
使用mark()方法,您可以在某个位置放置一个“标记”,然后继续阅读。一旦您意识到要返回标记的位置,就可以使用reset()进行返回。从这一点上,你再次读取相同的值。您可以将其用于任何需要的用途。假设您在BufferReader=“123456789”中有以下字符,如果您在相对于“5”字符的位置4处进行标记,然后重置缓冲读取器,您将得到12345。流的
标记和重置方法提供了在流中向后跳转并重新读取数据的方法
在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
本身已经支持标记和重置
!从内存中数据源读取的流通常支持标记
和重置
本身,因为它们的内存中已经有了所有数据,因此很容易再次读取。从文件、管道或网络套接字读取的流自然不支持标记和重置,但您始终可以将该功能添加到任何流中,方法是将其包装在BufferedInputStream
或BufferedReader
标记流中的特定点并重置()
将流重置为最新标记。这些方法提供了一个图书标记
功能,允许您在流中预读,以检查即将到来的数据
由此
mark()方法在输入中标记一个位置,通过该位置可以“重置”流
调用reset()方法。参数readLimit是
在设置之前的标记后可以从流中读取的字符
标记无效。例如,如果使用read调用mark()
限制为10,则当从流中读取11个字符的数据时
在调用reset()方法之前,标记无效,并且
流对象实例不需要记住标记。注意
此方法可以记住的字符数可以是
大于内部读取缓冲区的大小。也不是
取决于支持标记/重置的下级流
功能
文件说明:
设置此读卡器中的标记位置。参数readLimit指示
在标记无效之前可以读取多少个字符。
调用reset()会将读卡器重新定位到标记的位置
如果未超过读取限制
例如:
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
这里有一个例子
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
,这是一个很好的参考。这是答案的一半,什么是重置?Hey给出了一个正确的答案。重置只会将指向要读取的字符的指针带到标记的位置。如何调用Reset()
?我认为,如果您mark()
的读取限制为0,则一旦读取了一个字符,该标记就会无效,并且无法调用reset。您能解释一下您的答案吗?@snooze92只需运行此示例并尝试更改mark
方法中的markLimit
参数。你会一直得到相同的结果。另请参见类似示例:。实际上,我想提出一些问题,所以有人给了我一个解释。在运行了更多我自己的示例之后,我对标记(readAheadLimit)
/重置()
机制有了更好的理解。基本上,mark
方法只是在当前缓冲区中标记一个点,reset
允许您返回到该标记点。问题是,它并不意味着在文件或流中标记一个点,因为它需要增加缓冲区大小以保持访问标记点的可能性。这就是为什么我们应该使用一个相对小于缓冲区大小的限制。至于“为什么这个示例使用0的限制(或者任何限制)”也很容易解释。默认缓冲区大小(在两个示例中都使用)为4096。示例中使用的字符串非常小,一旦创建了BufferedReader,就会在第一个缓冲区中完全读取该字符串。它以后不再读取任何内容,因此根本不使用limit参数。。。让这个例子变得毫无意义,让IMHO感到困惑。稍微更改示例以在BufferedReader构造函数中添加非常小的缓冲区大小(例如2或3),将开始抛出无效的标记异常。@snooze92感谢您的解释。你对你的评论投了赞成票。你能帮个忙吗