1

我有一个二进制文件,它是 2 字节整数和 UTF-8 字符对的列表。我正在做的是

InputStream stream = ...;
InputStreamReader in = new InputStreamReader(stream);

while(...){
   stream.read(...);
   in.read();
}

也就是说,我直接从 InputStream 读取字节,并从同一文件流的 InputStreamReader 读取字符。对我来说,这看起来像是一个奇怪的(可怕的?)想法,但我没有看到其他方式。DataInputStream 只会读取 UTF-16 字符,而且我不知道我的 UTF-8 字符自己从字节中读取它需要多少字节(我不想重新发明 InputStreamReader)。此外,相同的方案适用于输出。

我的问题是,在读取第一对之后, InputStream.read 返回 -1 (当然,文件比那个长)。

我想知道是否有更好的选择,或者是否有其他原因导致 EOF。另外,如果这个方案没问题,我应该关闭 Reader 还是 InputStream?

4

1 回答 1

1

没错,您不想同时访问 InputStreamReader 及其底层 InputStream。您可能必须编写自己的 InputStreamReader 版本,但编写起来并不多:

byte[] bytes = new byte[4];

DataInputStream dataStream = new DataInputStream(stream);
while (dataStream.available() > 0) {
    int intValue = dataStream.readUnsignedShort();

    int charValue;
    int b = dataStream.read();
    if (b < 0x80) {
        charValue = b;
    }
    else {
        int byteCount;
        if (b >= 0xf0) {
            byteCount = 4;
        } else if (b >= 0xe0) {
            byteCount = 3;
        } else {
            byteCount = 2;
        }

        bytes[0] = (byte) b;
        dataStream.readFully(bytes, 1, byteCount - 1);
        String s = new String(bytes, 0, byteCount, 
            StandardCharsets.UTF_8);
        charValue = s.codePointAt(0);
    }

    // Do something with intValue and charValue
}
于 2012-12-12T11:28:38.583 回答