文字のすべてのインスタンスを削除するリーダーを書いているとします ('x' を削除しているとしましょう)。
次のように書くかもしれません:
public class ExampleReader extends FilterReader {
public ExampleReader(Reader in) {
super(in);
}
@Override
public int read() throws IOException {
int ch;
while ((ch = in.read()) != -1) {
if (ch != 'x') {
return ch;
}
}
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
int charsRead = in.read(cbuf, off, len);
if (charsRead == -1) {
return -1;
}
// srcPos will always be >= dstPos
int charsRemoved = 0;
int srcEnd = off + charsRead;
for (int srcPos = off, dstPos = off; srcPos < srcEnd; srcPos++, dstPos++) {
char ch = cbuf[srcPos];
if (ch == 'x') {
dstPos--;
charsRemoved++;
} else {
cbuf[dstPos] = cbuf[srcPos];
}
}
return charsRead - charsRemoved;
}
}
コード レビューで、別の開発者は、戻り値によると、 未満len
の値を返す場合、読み取ったスライスの外側に文字を記述していないはずだと主張しています。ただし、これはドキュメントにはまったく記載されていませんlen
。渡された値は、読み取る最大文字数であるとだけ書かれています。
私自身の見解では、渡された場合は、必要なlen
ものを書き込む許可が与えられており、off..off+len
たまたま少ない値を返す場合は、残りの配列の内容について保証していません。同様に、リーダーを呼び出している場合、返された範囲外のデータを読み取る意味があるとは想定しません。
誰が正しいですか?
(ちなみに、私が実際に実装したのは、行区切りの正規化、\r\n などを \n に変換することでした。Guava にはこれほど一般的なものがあったと確信していましたが、そうではなかったようです。それはめったにない仕事ですか?)