4

クライアント側にこのコードがあります:

DataInputStream dis = new DataInputStream(socketChannel.socket().getInputStream());
while(dis.available()){
     SomeOtherClass.method(dis);
}

しかし、ストリームに読み取り可能なデータがありますが、available()を返し続けます。0そのため、読み取られる実際のデータが終了した後、空のデータが読み取られる他のクラスに渡され、これが破損の原因になります。

少し検索した後; ソケットで使用する場合は信頼性available()が低く、ストリームから最初の数バイトを読み取って、データが解析可能かどうかを実際に確認する必要があることがわかりました。

しかし、私の場合は; DataInputStreamソケットから取得した参照を、変更できない他のクラスに渡す必要があります。

破損せずに数バイトを読み取ることは可能DataInputStreamですか、または他の提案はありますか?

4

3 に答える 3

5

PushbackInputStreamを間に置くと、データを破損することなくいくつかのバイトを読み取ることができます。

編集:以下のテストされていないコード例。これはメモリからです。

static class MyWrapper extends PushbackInputStream {
    MyWrapper(InputStream in) {
        super(in);
    }

    @Override
    public int available() throws IOException {
        int b = super.read();
        // do something specific?
        super.unread(b);
        return super.available();
    }
}

public static void main(String... args) {
    InputStream originalSocketStream = null;
    DataInputStream dis = new DataInputStream(new MyWrapper(originalSocketStream));
}
于 2012-08-16T07:52:36.887 に答える
2

これはうまくいくはずです:

PushbackInputStream pbi = new PushbackInputStream(socketChannel.socket().getInputStream(), 1);
int singleByte;
DataInputStream dis = new DataInputStream(pbi);
while((singleByte = pbi.read()) != -1) {
    pbi.unread(singleByte);
    SomeOtherClass.method(dis);
}

ただし、このコードは available を使用した例とは異なる動作をすることに注意してください (availabe が機能する場合)。

于 2012-08-16T08:13:53.097 に答える
1

しかしavailable()、ストリームに読み取り可能なデータがあるにもかかわらず、0 を返し続けます

available()ゼロを返す場合は、次のいずれかです。

  1. 使用している入力ストリームはサポートされていないためavailable()、ゼロが返されます。ここではそうではありません。DataInputStreamソケットの入力ストリームに直接ラップされた を使用しており、その構成ではavailable(), OR ...がサポートされているためです。

  2. ストリームに読み取り可能なデータがありません。ここではそのようです。実際、ストリームに読み取り可能なデータがあることを実際に読み取らずに知ることができる唯一の方法は、呼び出しavailable()て肯定的な結果を取得することです。他に伝える方法はありません。

の正しい使い方はほとんどなくavailabe()、これはその 1 つではありません。ソケット受信バッファーにデータがないという理由だけで、なぜそのループから抜け出す必要があるのでしょうか? そのループから抜け出す唯一の方法は、ストリームの終了条件を取得することです。

ストリームから最初の数バイトを読み取って、データが解析可能かどうかを実際に確認する必要があります。

それは意味がありません。ストリームから何かを読み取ることができれば、利用可能なデータがあり、できない場合はありません。

EOS のさまざまな症状を読み取り、ブロックし、正しく対応するだけです。

于 2012-08-16T10:22:17.837 に答える