5

着信 HttpServletRequest (以下の「リクエスト」) からリクエスト ストリーム (gzip 圧縮されたデータを含む) を読み取るために何かを書いていますが、通常の InputStream 読み取りメソッドは実際にはすべてのコンテンツを読み取らないようです。

私のコードは次のとおりです。

InputStream requestStream = request.getInputStream();
if ((length = request.getContentLength()) != -1)
{
    received = new byte[length];
    requestStream.read(received, 0, length);
}
else
{
    // create a variable length list of bytes
    List<Byte> bytes = new ArrayList<Byte>();

    boolean endLoop = false;
    while (!endLoop)
    {
        // try and read the next value from the stream.. if not -1, add it to the list as a byte. if
        // it is, we've reached the end.
        int currentByte = requestStream.read();
        if (currentByte != -1)
            bytes.add((byte) currentByte);
        else
            endLoop = true;
    }
    // initialize the final byte[] to the right length and add each byte into it in the right order.
    received = new byte[bytes.size()];
    for (int i = 0; i < bytes.size(); i++)
    {
        received[i] = bytes.get(i);
    }
}

テスト中に私が見つけたのは、上部 (コンテンツの長さが存在する場合) が着信要求ストリームの途中で読み取りを停止し、「受信した」バイト配列の残りを空白のままにすることがあるということでした。if ステートメントの else 部分を常に実行するようにすると、正常に読み取られ、予想されるすべてのバイトが「受信済み」に配置されます。

したがって、その変更でコードをそのままにしておくことができるようですが、通常の 'read'(byte[], int, int)' メソッドが読み取りを停止した理由を知っている人はいますか? 説明によると、ファイルの終わりが存在する場合は停止する可能性があります。gzip されたデータに、その署名がどのように見えるかに一致するバイトがたまたま含まれていた可能性はありますか?

4

2 に答える 2

9

whileすべてのバイトを取得するには、上部にループを追加する必要があります。ストリームはできるだけ多くのバイトを読み込もうとしますがlen、一度にバイトを返す必要はありません:

len バイトまで読み取ろうとしますが、それよりも小さい数 (おそらくゼロ) が読み取られる可能性があります。

if ((length = request.getContentLength()) != -1)
{
    received = new byte[length];
    int pos = 0;
    do {
        int read = requestStream.read(received, pos, length-pos);

        // check for end of file or error
        if (read == -1) {
            break;
        } else {
            pos += read;
        }
    } while (pos < length);
}

編集:修正中。

于 2012-08-13T15:59:12.787 に答える
1

バッファがどれだけ満たされたかを確認する必要があります。少なくとも 1 バイトを提供することが保証されているだけです。

おそらく、あなたが欲しかったのはDataInputStream.readFully() ;

于 2012-08-13T15:57:53.703 に答える