BufferedInputStream的mark()方法不如预期工作

huangapple go评论78阅读模式
英文:

BufferedInputStream.mark() method not working as expected

问题

Code :

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

What does this code do?

This code reads the provided string and uses a buffered stream to process it. It handles comments marked with #This_Is_Comment# and preserves content within these comments. However, comments with #This is not comment# are not treated as comments and are directly output.

Question:

In the part of the code where space (' ') is encountered, and the com boolean value is true, the code reverts the stream to the marked position. There's a doubt about whether encountering '#' again would set com to false, thus considering it a comment.

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

However, this isn't the case, and the output is correct.

英文:

Code :

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

    }
}

What does this code do?

This code reads the String and the bufferStream removes/hides comments. Here comments are denoted by #this_is_comment# and comments with ' ' (space) is not considered comment ex :
#This is not comment#.

Question:

Whenever ' ' (space) is encountered and com (boolean value, when true does not read the stream) is true it reverts the stream to the marked position, my doubt is that if it reverts, wouldn't the # be encountered again and com will be set to false hence considering it comment.

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

but this is not the case the output is correct.

BufferedInputStream的mark()方法不如预期工作

If possible please edit the question to make it more understandable.

答案1

得分: 1

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

方法.mark()markPos设置为pos

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

问题是,pos是谁?只需转到其定义,将在JavaDoc中找到以下内容(仅报告相关部分):

/**
 * 缓冲区中的当前位置。这是要从<code>buf</code>数组中读取的下一个字符的索引。
 * <p>
 * ... 更多的JavaDoc
 */
protected int pos;

因此,当您调用.reset()时,您正在执行以下操作:

public synchronized void reset() throws IOException {
    getBufIfOpen(); // 如果关闭则引发异常
    if (markpos < 0)
        throw new IOException("Resetting to invalid mark");
    pos = markpos;
}

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

简而言之

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

这就是为什么您的代码不会再次进入注释部分的原因。

英文:

The behavior is expected. If you read the implementation of the methods .mark() and .read() of BufferedInputStream, you can see that:

The method .mark() sets markPos to pos:

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

The question is who is pos? Just go to its definition and will find this in JavaDoc (only reporting the relevant part):

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

Hence, when you call .reset() you're doing this:

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

Basically, you're restoring the last "next character" of your stream.

To make it simple

According to the official JavaDoc of BufferedInputStream, if you are in a String s = &quot;Hello World&quot; and you call .mark() while reading character W, when you do .reset() you will restart from the next character after W which is o.

This is why your code doesn't fall in the comment part again.

huangapple
  • 本文由 发表于 2020年7月25日 16:43:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63086262.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定