5

我一直在写一些东西来从传入的 HttpServletRequest (下面的“请求”)读取请求流(包含压缩数据),但是看起来普通的 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 部分,它会正常读取,并且所有预期的字节都放在“已接收”中。

因此,似乎我现在可以通过该更改单独保留我的代码,但是有人知道为什么正常的“读取”(字节[],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

您需要查看填充了多少缓冲区。它只保证给你至少一个字节。

也许你想要的是DataInputStream.readFully()

于 2012-08-13T15:57:53.703 回答