-1

BufferedInputStream.read(byte[]) についての私の理解では、読み取り操作は pos から始まり、バイト配列がいっぱいになるか、ストリームの終わりが発生するまで読み取ります。

以下の BufferedInputStream で readInt メソッドを呼び出しています。

public class XDRInputStream {

private InputStream stream;

private byte[] buffer4 = new byte[4]; // fixed size buffers
private byte[] buffer8 = new byte[8];

public XDRInputStream(InputStream stream) {
    this.stream = stream;
}

public InputStream getInternalStream() {
    return stream;
}

public int readInt() throws IOException {
    if (stream.read(buffer4) != -1) {
        return ((buffer4[0] & 0xFF) << 24)
             | ((buffer4[1] & 0xFF) << 16)
             | ((buffer4[2] & 0xFF) << 8)
             | ((buffer4[3] & 0xFF));
    } else {
        throw new EOFException("End of stream");
    }
}

Eclipse デバッガーで実行を追跡すると、stream.read(buffer4)呼び出しは、最初の pos 値に関係なく、通常、pos の値が 4 に設定され、読み込まれた 4 バイトは入力ストリームからの最初の 4 バイトになります。read(byte[]) 呼び出しは、特定の状況でストリームを静かにリセットしますか? もしそうなら、いつですか? これは意図した動作のようです (これは私のコードではありません)。このように動作すると、プログラムは正常に機能します。

私が経験している問題は、Windows でのみ、入力ストリームに特定のコンテンツが含まれている場合 (この場合、アップストリームのソケットがドロップされたためにエラー メッセージが表示される場合) にのみ、この pos のリセットが意図されていると思われる場合に発生しないことがあります。これにより、メソッドはストリーム内の不適切な位置から読み取り、不適切な値を返します。

Solaris でも同じコードを使用しています。このプラットフォームではデバッガーのステップスルーを行っていませんが、Solaris ではプログラムは正常に動作し、修正しようとしているバグは発生しません。私が認識していないストリームにプラットフォーム固有の問題がある可能性はありますか?

ありがとう。

4

2 に答える 2

2

経験則として、配列全体がストリームから一度に読み取られるとは限りません。ドキュメントを見ると、戻り値がread(byte[])読み取られたバイト数であり、配列全体の長さ以下であることがわかります。または、データがまだ存在しない場合は 0 です。そして、配列全体よりも少ないものを読み取ることは非常に一般的です (そしておそらく OS に依存します)。

したがって、実際に 4 バイトを読み取ったことを確認する必要があります。

于 2012-07-10T05:47:15.247 に答える
1

BufferedInputStream.read(byte [])についての私の理解は、読み取り操作はposから始まり、バイト配列がいっぱいになるか、ストリームの終わりが発生するまで読み取ります。

あなたの理解は間違っています。

あなたの理解は、少なくとも1バイトが利用可能になるまで必要に応じてブロックし、利用可能なものをすべて読み取り、読み取られたバイト数のカウントを返す、またはEOSが代わりに読み取られた場合は-1を返すというJavadocとはまったく矛盾しています。

于 2012-07-10T09:57:23.303 に答える