Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/54.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java BufferedReader中的标记和重置是什么?_Java_Stream_Bufferedreader - Fatal编程技术网

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感谢您的解释。你对你的评论投了赞成票。你能帮个忙吗