BufferedInputStream.mark() 方法未按预期工作

BufferedInputStream.mark() method not working as expected

代码:

import java.io.*;
public class BufferedInputStreamDemo {
    public static void main(String[] args) throws IOException {
        String phrase = "Hello World #This_Is_Comment# #This is not comment#";
        byte[] bytes = phrase.getBytes();
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        BufferedInputStream bin = new BufferedInputStream(in);
        int character;
        boolean com = false;
        while ((character = bin.read()) != -1) {
            switch(character) {
                case '#' :
                    if (com) com = false;
                    else {
                        com = true;
                        bin.mark(1000);
                    }
                    break;
                case ' ' :
                    if (com) {
                        com = false;
                        System.out.print('#');
                        bin.reset();
                    }
                    else  {
                        System.out.print((char)character);
                    }
                    break;
                default : if (!com) System.out.print((char)character);
            }
        }
        in.close(); bin.close();

    }
}

这段代码有什么作用?

此代码读取字符串和 bufferStream removes/hides 注释。这里的评论用 #this_is_comment# 表示,带有 ' ' (space) 的评论不被视为评论 ex : #这不是评论#.

问题:

每当遇到 ' ' (space) 并且 com(布尔值,当 true 不读取流)为真时,它会将流恢复到标记位置,我怀疑如果它恢复,不会再次遇到 # 并且 com 将被设置为 false 因此考虑它的评论。

case '#' :
        if (com) com = false;
        else {
            com = true;
            bin.mark(1000);
        }

但事实并非如此,输出是正确的。

如果可能,请编辑问题以使其更易于理解。

该行为是预期的。如果你阅读BufferedInputStream的方法.mark().read()的实现,你可以看到:

方法.mark()markPos设置为pos:

public synchronized void mark(int readlimit) {
    marklimit = readlimit;
    markpos = pos;
}

问题是谁pos?只要去它的定义,就会在JavaDoc中找到这个(只报告相关部分):

/**
 * The current position in the buffer. This is the index of the next
 * character to be read from the <code>buf</code> array.
 * <p>
 * ... more JavaDoc
 */
protected int pos;

因此,当您调用 .reset() 时,您这样做:

public synchronized void reset() throws IOException {
    getBufIfOpen(); // Cause exception if closed
    if (markpos < 0)
        throw new IOException("Resetting to invalid mark");
    pos = markpos;
}

基本上,您正在恢复流的最后一个“下一个字符”。

为简单起见[​​=42=]

根据 BufferedInputStream 的官方 JavaDoc,如果您在 String s = "Hello World" 中并且在读取字符 W 时调用 .mark(),当您执行 .reset() 您将从 W 之后的下一个字符重新开始,即 o.

这就是为什么你的代码没有再次出现在评论部分的原因。