7

DataInputStreamを使用して、ソケットからいくつかのバイトを読み取ります。ストリームから読み取るバイト数が予想されます(ヘッダーをデコードした後、メッセージに含まれるバイト数がわかります)99%の時間は機能しますが、読み取られるバイト数がlen未満になる場合があります。

int numRead = dis.read(buffer, 0, len);

numReadがlen未満になる原因は何ですか?-1ではありません。ストリームが閉じられるかEOFに達するまで、読み取りの動作がブロックされると予想しますが、ストリームの基盤となるソケットの場合、ソケットが閉じない限り、これは発生しないはずです。

常にlenバイトを読み取ることを保証するソケットからバイトを読み取る方法はありますか?

ありがとう

4

5 に答える 5

12

編集: 一般的なストリームの場合、基本的に読みたいものをすべて読み終え​​るまで読み続けます。DataInput( などの)の実装については、Peter Lawrey が提案したように、 をDataInputStream使用する必要があります。readFullyこの回答の残りの部分は、InputStream.

より多くのデータが処理中であっても、どのタイプのが要求したよりも少ないデータを提供することは完全に合理的です。InputStreamこの可能性を考慮して、常にコーディングする必要がありますByteArrayInputStream。(もちろん、要求したよりも少ないデータが残っている場合は、要求されたよりも少ないデータが返される可能性があります。)

これが私が話している種類のループです:

byte[] data = new byte[messageSize];
int totalRead = 0;

while (totalRead < messageSize) {
    int bytesRead = stream.read(data, totalRead, messageSize - totalRead);
    if (bytesRead < 0) {
        // Change behaviour if this isn't an error condition
        throw new IOException("Data stream ended prematurely");
    }
    totalRead += bytesRead;
}
于 2011-01-12T20:59:04.567 に答える
9

このように DataInputStream を使用できます。

byte[] bytes = new byte[len];
dis.readFully(bytes);

これにより、すべてのデータが読み取られて返されるか、IOException がスローされます。

于 2011-01-12T21:33:17.790 に答える
0

read はその時点で利用可能だったビットで毎回返され、完了すると -1 になります。

while (true) {
  int numRead = dis.read(buffer, 0, len);
  if (numRead == -1) break;
  total.append(buffer, numRead);
}
于 2011-01-12T21:01:56.170 に答える
0

ストリームが閉じられるか EOF に達するまで、 read の動作がブロックされることを期待します。

次に、Javadocs を確認する必要があります。read() のコントラクトは、少なくとも 1 バイトを読み取り、必要に応じて読み取りが完了するまで、または EOS または例外が発生するまでブロックすることです。要求された長さ全体を読み取るという仕様書はありません。そのため、長さを返します。

于 2011-01-13T05:19:15.063 に答える