1

2バイト整数とUTF-8文字のペアのリストであるバイナリファイルがあります。私がしているのは

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

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

つまり、InputStreamからバイトを直接読み取り、同じファイルストリームのInputStreamReaderからcharを読み取ります。これは私には奇妙な(ひどい?)考えのように見えますが、別の方法はわかりません。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 に答える