java.io.IOException:标记无效

时间:2017-08-08 22:03:52

标签: java reset ioexception markers

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。

3 个答案:

答案 0 :(得分:2)

public void mark(int readAheadLimit)
      throws IOException
  

标记流中的当前位置。后续调用reset()   将尝试将流重新定位到这一点。

     

...

     

参数:

     

readAheadLimit - 限制在保留标记的同时可以读取的字符数。尝试重置流   阅读完这个极限或更高的字符后可能会失败。一个限制   大于输入缓冲区大小的值将导致新的缓冲区   被分配的大小不小于限制。因此大   值得谨慎使用。

您将readAheadLimit设置为1个字符,然后读取整行。这使商标无效。

答案 1 :(得分:1)

为此,我们需要了解 BufferedReader 的工作原理...

BufferReader 将一次性读取 8192 个字符并将其存储在字符缓冲区 - cb(默认值可以更改)中。

readLine() - 将尝试从字符缓冲区中获取数据,如果需要的字符数超过可用字符数,它将再次进行获取,并且 < em>填充接下来的 8192 个字符...

ma​​rk() - 用于制作当前行,以便使用 reset() 方法我们可以回到之前标记的那一行。

ma​​rk() 方法接受一个参数 - 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)方法时将缓冲区增大。