英文:
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.
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 <code>buf</code> array.
* <p>
* ... 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 < 0)
throw new IOException("Resetting to invalid mark");
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 = "Hello World"
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论