java - 扩展 InputStreamReader 无法正常工作
问题描述
我以这种方式扩展 InputStreamReader
public class AsteriskInputStreamReader extends InputStreamReader {
boolean ast;
AsteriskInputStreamReader(InputStream is) {
super(is);
}
@Override
public int read() throws IOException {
ast = !ast;
if (ast) return '*';
return super.read();
}
}
它必须在从原始InputStream
. 但是当我这样使用它时
InputStreamReader in = new AsteriskInputStreamReader(new FileInputStream("text.txt"));
int c;
while((c = in.read()) != -1){
System.out.print((char)c);
}
它仅适用于文件中的最后一行。前几行仅输出为一个“*”,没有任何文本。为什么?
第二个问题。
当我BufferedInputStream
用它创建并尝试获取文件的第一行时
BufferedReader reader = new BufferedReader(in);
System.out.println(reader.readLine());
我得到文件的第一行没有任何'*'。
获得我想要的东西的正确方法是什么:创建包装器InputStreamReader
,它将在原始输入的所有符号之后添加星号符号?
解决方案
而不是子类化InputStreamReader
,创建一个单独Reader
的,您可以与其他阅读器链接,因此您也可以将其应用于不支持的阅读器InputStream
。
try (BufferedReader reader = new BufferedReader(
new AsteriskReader(
new InputStreamReader(
new FileInputStream("text.txt"))))) {
// ...
}
格式化以强调链。
它不起作用的原因是BufferedReader
它不会调用read()
您覆盖的方法,它会调用采用缓冲区(、、或)的read(char[] cbuf)
重载read(char[] cbuf, int off, int len)
之一read(CharBuffer target)
。
要实现一个Reader
要被链接的子类FilterReader
。
class AsteriskReader extends FilterReader {
private boolean ast;
private boolean astMarked;
public AsteriskReader(Reader in) {
super(in);
}
@Override
public int read() throws IOException {
// TODO Add handling of EOF
ast = !ast;
if (ast) return '*';
return super.read();
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
// TODO Implement this, i.e. only read half number of characters from
// underlying reader, then inject '*' characters between all the
// chars actually read.
// Special handling for odd value of len.
int charsRead = super.read(cbuf, off, len);
return charsRead;
}
@Override
public long skip(long n) throws IOException {
// TODO Fix this to handle odd value of n.
long actualSkipped = super.skip(n / 2);
return actualSkipped * 2;
}
@Override
public void mark(int readAheadLimit) throws IOException {
super.mark((readAheadLimit + 1) / 2); // Underlying reader only needs to remember half
this.astMarked = this.ast;
}
@Override
public void reset() throws IOException {
super.reset();
this.ast = this.astMarked;
}
}