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
.
这就是为什么你的代码没有再次出现在评论部分的原因。
代码:
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
.
这就是为什么你的代码没有再次出现在评论部分的原因。