0

假设您正在编写一个删除所有字符实例的阅读器(假设您正在删除“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 中会有如此常见的东西,但它似乎不是。真的这么稀有的任务?)

4

1 回答 1

0

InputStream.read()的Javadoc说“这些字节将存储在元素 b[off] 到 b[off+k-1] 中,而元素 b[off+k] 到 b[off+len-1] 不受影响。 " 它没有被重申,Reader.read()但显然应该如此。

于 2013-11-12T00:52:14.970 回答