输入流,标记(),重置()
Posted
技术标签:
【中文标题】输入流,标记(),重置()【英文标题】:InputStream, mark(), reset() 【发布时间】:2012-10-23 04:49:52 【问题描述】:mark()
和 reset()
方法是如何工作的(在下面的代码中),一步一步?我尝试编写自己的示例,但开始抛出错误的标记异常或类似的异常,我无法理解在此代码中放置标记和重置方法的意义何在,因为我看不出有没有区别。
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);
【问题讨论】:
抛出了什么异常?你有堆栈跟踪吗?请更具体地说明您的问题。 被抛出的异常是I/O Error: java.io.IOException: Resetting to invalid mark
,但是我写了那个异常被抛出另一个例子。我主要是问 this example 中的 mark(32) 和 reset 是什么。
【参考方案1】:
查看 API 文档:
mark(int)
标记此输入流中的当前位置。对 reset 方法的后续调用会将此流重新定位到最后标记的位置,以便后续读取重新读取相同的字节。
readlimit 参数告诉这个输入流允许在标记位置失效之前读取那么多字节。
这个方法只是简单地执行 in.mark(readlimit)。
reset()
将此流重新定位到上次在此输入流上调用标记方法时的位置。
这个方法只是简单地执行 in.reset()。
流标记旨在用于需要提前阅读以查看流中内容的情况。通常这最容易通过调用一些通用解析器来完成。如果流是由解析处理的类型,它就会愉快地前进。如果流不是那种类型,解析器应该在失败时抛出一个异常。如果这发生在 readlimit 字节内,它允许外部代码重置流并尝试另一个解析器。
【讨论】:
【参考方案2】:当到达f.mark(32);
时,读取光标已经在&
之后,并且为reset
设置了一个标记以知道从哪里跳回。因此,当您检测到缺少;
以关闭元素时,您将手动打印&
并将读取光标向右移动(在放置标记的&
之后,使用mark(32)
调用),使用reset
方法。在下一次读取时,因为您的 marked
变量未设置,它将打印字符。
mark(32)
表示如果您的阅读光标前进超过 32 个字符,则自动删除标记。这可能是您的其他代码中的问题,即触发错误,因为标记已经失效。
【讨论】:
以上是关于输入流,标记(),重置()的主要内容,如果未能解决你的问题,请参考以下文章