简体   繁体   English

java.io.IOException:标记无效

[英]java.io.IOException: Mark invalid

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();
        } ...

Why is the markedChar value changing to -2 after passing the if-statement?为什么在传递 if 语句后,markedChar 值变为 -2?

Thx for every answer Nico.每个答案都感谢尼科。

public void mark(int readAheadLimit)
      throws IOException

Marks the present position in the stream.标记流中的当前位置。 Subsequent calls to reset() will attempt to reposition the stream to this point.对 reset() 的后续调用将尝试将流重新定位到这一点。

... ...

Parameters:参数:

readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. readAheadLimit - 限制在保留标记的同时可以读取的字符数。 An attempt to reset the stream after reading characters up to this limit or beyond may fail.在读取达到或超过此限制的字符后尝试重置流可能会失败。 A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit.大于输入缓冲区大小的限制值将导致分配大小不小于限制的新缓冲区。 Therefore large values should be used with care.因此,应谨慎使用较大的值。

You set the readAheadLimit to 1 character then read an entire line.您将readAheadLimit设置为 1 个字符,然后读取整行。 This invalidated the mark.这使商标无效。

For this, we need to understand how the BufferedReader works...为此,我们需要了解BufferedReader是如何工作的......

BufferReader will read 8192 characters at one shot and store it in a character buffer - cb (default value can be changed). BufferReader 将一次性读取 8192 个字符并将其存储在字符缓冲区 - cb 中(默认值可以更改)。

readLine() - will try to fetch the data from the character buffer, if it needs more characters than what is available, it will do a fetch again and fill the next 8192 characters... readLine() - 将尝试从字符缓冲区中获取数据,如果需要的字符数超过可用字符数,它将再次进行获取并填充接下来的 8192 个字符...

mark() - is used to make the current line, so that using reset() method we can go back to the previously marked line. mark() - 用于制作当前行,以便使用reset()方法我们可以回到之前标记的行。

mark() method takes a parameter - readAheadLimit , which should be the maximum number of characters in that line. mark()方法接受一个参数 - readAheadLimit ,它应该是该行中的最大字符数。

As given in the Java DOCS - having a limit less than the line size may fail.正如 Java DOCS 中给出的那样 - 限制小于行大小可能会失败。 https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#mark(int) https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#mark(int)

If we try to fill the character array again after the character buffer array is exhausted and the number of pending characters is more than the marked limit (readAheadLimit).如果我们在字符缓冲区数组耗尽并且待处理字符数超过标记限制(readAheadLimit)后再次尝试填充字符数组。 It will mark the markedChar as INVALIDATED.它将标记的Char 标记为INVALIDATED。 The next call to reset will lead to IOException - Mark invalid下一次调用 reset 会导致 IOException -标记无效

CONCLUSION:结论:

Make sure that the readAheadLimit is the maximum number of characters that can be present in a line.确保readAheadLimit是一行中可以出现的最大字符数。

If the line is already filled in the character buffer, you will not get any error since the check is done while trying to fill the character buffer again.如果该行已经填充到字符缓冲区中,您将不会收到任何错误,因为在尝试再次填充字符缓冲区时已完成检查。

That is the significance of may fail in Java Docs.这就是 Java Docs 中可能失败的意义。

I had the same problem with that damn exception: Mark Invalid.我对那个该死的异常有同样的问题: Mark Invalid.

I came to this forum and I did not find something that would work so I had to figure out for myself what happens.我来到这个论坛,但没有找到可行的方法,所以我必须自己弄清楚会发生什么。

The BufferedReader creates a buffer (who would say it) from the moment I call the BufferedReader :: mark (int readAheadLimit) function, the size of the buffer IN CHARACTERS (NOT LINES) is given by readAheadLimit.从我调用 BufferedReader :: mark (int readAheadLimit) 函数的那一刻起,BufferedReader 就创建了一个缓冲区(谁会说),缓冲区的大小(字符(非行))由 readAheadLimit 给出。

Once this limit is exceeded, it is not possible to go back with BufferedReader :: reset (), at the time of the mark because although the first data of the buffer could be recovered the later ones (those after the maximum of the buffer size and before the position current file) it would not be possible to retrieve them.一旦超过这个限制,就不可能在标记的时候用 BufferedReader::reset() 返回,因为虽然缓冲区的第一个数据可以恢复到后面的数据(那些在缓冲区大小的最大值之后)在位置当前文件之前)将无法检索它们。

To avoid errors, the mark is invalidated by setting it to -2, and when the reset is called, the exception is produced: Mark Invalid.为避免错误,通过将标记设置为-2 来使标记无效,并且在调用重置时,会产生异常: Mark Invalid. The issue is that it is NOT POSSIBLE with BufferedReader, to go back the pointer to read the file, it is simulated by storing the data in memory (the buffer).问题是BufferedReader不可能返回指针来读取文件,它是通过将数据存储在内存(缓冲区)中来模拟的。

So if you run into an Invalid Mark exception, you should make the buffer larger when calling the mark (int) method.所以如果遇到 Invalid Mark 异常,在调用 mark(int) 方法时应该把缓冲区变大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM