InputStream,mark(),reset()
mark()
和reset()
方法如何正常工作(在下面的代码中),一步一步? 我试着编写我自己的例子,但是开始抛出错误的标记exception或者类似的东西,我无法理解在这段代码中放置标记和重置方法有什么意义,因为我看不出这个或没有区别。
import java.io.*; class BufferedInputStreamDemo { public static void main(String args[]) { String s = "© is a copyright symbol, " + "however © isn't.\n"; byte buf[] = s.getBytes(); ByteArrayInputStream in = new ByteArrayInputStream(buf); int c; boolean marked = false; //try_with_resources try (BufferedInputStream f = new BufferedInputStream(in)) { while ((c = f.read()) != -1) { switch (c) { case '&': if (!marked) { f.mark(32); marked = true; } else { marked = false; } break; case ';': if (marked) { marked = false; System.out.print("(c)"); } else System.out.print((char) c); break; case ' ': if (marked) { marked = false; f.reset(); System.out.print("&"); } else System.out.print((char) c); break; default: if (!marked) System.out.print((char) c); break; } } } catch (IOException e) { System.out.println("I/O Error: " + e); } } }
当f.mark(32);
到达后,读取光标已经在&
之后,并且标记被设置为reset
以知道在哪里跳回。 所以,当你检测到一个;
缺少关闭元素,您使用reset
方法手动打印并向后移动读取光标(放置标记的位置和之后,使用mark(32)
调用)。 在下一次阅读时,由于未设置marked
变量,因此将打印字符。
mark(32)
表示如果读取的光标超过32个字符,则自动删除标记。 这可能是您的其他代码中的问题,即触发错误,因为标记已经失效。
请参阅API文档:
mark(int)
标记此输入流中的当前位置。 随后对reset方法的调用会在最后标记的位置重新定位此流,以便后续读取重新读取相同的字节。
readlimit参数告诉此输入流允许在标记位置失效之前读取许多字节。
此方法只执行in.mark(readlimit)。
reset()
将此流重新定位到上次在此输入流上调用mark方法时的位置。
此方法只执行in.reset()。
流标记旨在用于需要提前阅读以查看流中的内容的情况。 通常,这通过调用一些通用解析器最容易完成。 如果流是由解析处理的类型,那么它只是愉快地开始。 如果流不是该类型,则解析器在失败时应该抛出exception。 如果这发生在readlimit字节内,它允许外部代码重置流并尝试另一个解析器。