如何实现自定义FilterReader?

时间:2016-03-19 20:53:01

标签: java bufferedreader filereader streamreader reader

我正在尝试实现自定义的FilterReader类。该类应该改变它所读取的内容(更不用说如何)。我遇到的问题是转换后的字符串比读入char缓冲区的原始字符串长,所以当我尝试将新字符串塞入缓冲区时,我得到一个ArrayIndexOutOfBoundsException

这是我的自定义FilterReader类的read()方法:

@Override
public int read(char[] cbuf, int off, int len) throws IOException {
    int result = in.read(cbuf, off, len);

    if( result != -1 ){
        String str = new String(cbuf, off, len);
        str = someStringTranformationMethod(str);

        //cbuf = new char[str.length()];

        str.getChars(0, str.length(), cbuf, 0);

        result = str.length();
    }

    return result;
}

我以为我可以通过为cbuf重新分配一个新的char缓冲区来解决它,这是我在注释行中尝试的。但是,这似乎根本不起作用,因为我的读者输出是原始的(未转换的)字符串。

我有一种感觉,我在这里完全倒退了,但要在网上找到这些东西的好例子并不容易。我找到的所有自定义FilterReader都刚刚完成了字符的一些基本上/下框,其中新字符串的长度与原始字符串的长度相同。

那么我如何使用字符串转换函数来实现它,这会导致字符串比原始字符串更长?

1 个答案:

答案 0 :(得分:2)

您需要使您的实现有状态并跟踪“剩余”字符:

private String str = "";
private int pos = 0;

public int read(char[] cbuf, int off, int len) throws IOException {
  if (pos == str.length()) {
    // No leftovers from a previous call available, need to actully read more
    int result = in.read(cbuf, off, len);
    if( result <= 0 ){
      return -1;
    }
    str = new String(cbuf, off, result);
    str = someStringTranformationMethod(str);
    pos = 0;
  }

  // Return as much as we have available, but not more than len
  int available = Math.min(str.length() - pos, len);     
  str.getChars(pos, pos + available, cbuf, off);
  pos += available;
  return available;
}

请注意,如果尚未到达流的末尾,则read()只需要只读(at least)一个字符。这种实现利用了这一点。