我一直在写一些内容来从传入的HttpServletRequest(下面的'request')读取请求流(包含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部分,它就会正常读取并且所有预期的字节都放在'received'中。
所以,似乎我现在可以单独留下我的代码,但是有没有人知道为什么正常的'read'(byte [],int,int)'方法停止了读取?描述说如果存在文件结尾,它可能会停止。可能是gzip压缩的数据恰好包含匹配任何签名的字节吗?
答案 0 :(得分:8)
您需要在顶部添加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);
}
编辑:修复了。
答案 1 :(得分:1)
您需要查看填充了多少缓冲区。它只能保证至少给你一个字节。
也许你想要的是DataInputStream.readFully();