public void createNewUser(String name, String passwort) {
try {
br = new BufferedReader(new FileReader("Data.txt"));
} catch (FileNotFoundException brCreateError) {
brCreateError.printStackTrace();
}
try {
br.mark(1);
System.out.println(br.readLine());
try {
if(br.readLine()==null) {
noUser=true;
}else {
noUser=false;
}
} catch (IOException e) {
e.printStackTrace();
}
br.reset();
} catch (IOException brMarkError) {
brMarkError.printStackTrace();
} ...
为什么在传递if语句后,markedChar值会变为-2?
每个答案的Nx Nico。
答案 0 :(得分:2)
public void mark(int readAheadLimit)
throws IOException
标记流中的当前位置。后续调用reset() 将尝试将流重新定位到这一点。
...
参数:
readAheadLimit
- 限制在保留标记的同时可以读取的字符数。尝试重置流 阅读完这个极限或更高的字符后可能会失败。一个限制 大于输入缓冲区大小的值将导致新的缓冲区 被分配的大小不小于限制。因此大 值得谨慎使用。
您将readAheadLimit
设置为1个字符,然后读取整行。这使商标无效。
答案 1 :(得分:1)
为此,我们需要了解 BufferedReader 的工作原理...
BufferReader 将一次性读取 8192 个字符并将其存储在字符缓冲区 - cb(默认值可以更改)中。
readLine() - 将尝试从字符缓冲区中获取数据,如果需要的字符数超过可用字符数,它将再次进行获取,并且 < em>填充接下来的 8192 个字符...
mark() - 用于制作当前行,以便使用 reset() 方法我们可以回到之前标记的那一行。
mark() 方法接受一个参数 - readAheadLimit,它应该是该行中的最大字符数。
如 Java DOCS 中所述 - 限制小于行大小可能失败。 https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#mark(int)
<块引用>如果我们尝试在字符缓冲区之后再次填充字符数组 数组已用完,待处理字符数超过 标记的限制(readAheadLimit)。它将标记的Char标记为 无效。下一次调用 reset 会导致 IOException - Mark 无效
结论:
确保 readAheadLimit 是一行中可以出现的最大字符数。
如果该行已经填充到字符缓冲区中,您将不会收到任何错误,因为在尝试再次填充字符缓冲区时已完成检查。
这就是 may fail 在 Java 文档中的重要性。
答案 2 :(得分:0)
该死的异常我也遇到了同样的问题:Mark Invalid.
我来到了这个论坛,但没有找到任何可行的方法,因此我不得不自己弄清楚会发生什么。
从我调用BufferedReader ::标记(int readAheadLimit)函数的那一刻起,BufferedReader就会创建一个缓冲区(可以说出来),该缓冲区的大小由readAheadLimit确定。
一旦超过此限制,就无法在标记时返回BufferedReader :: reset(),因为尽管可以恢复缓冲区的第一个数据,但后面的可以恢复(最大缓冲区数之后的数据)。缓冲区的大小,并且在当前文件的位置之前),将无法检索它们。
为避免错误,通过将标记设置为-2来使标记无效,并且在调用重置时,会产生异常:Mark Invalid.
问题是,对于BufferedReader来说,它不可能指针来读取文件,它是通过将数据存储在内存(缓冲区)中来模拟的。
因此,如果遇到Invalid Mark异常,则应在调用mark(int)方法时将缓冲区增大。