通过 HttpURLConnection 远程拉一个30M的文件拉下来的文件比源文件小,看了一下response header里是ransfer-Encoding: chunked但不知道怎么解析,希望有大牛能提供一下解析思路以及解析代码,谢谢!
Transfer-Encoding: chunked 表示输出的内容长度不能确定,普通的静态页面、图片之类的基本上都用不到这个。
但动态页面就有可能会用到,但我也注意到大部分asp,php,asp.net动态页面输出的时候大部分还是使用Content-Length,没有使用Transfer-Encoding: chunked。
不过如果结合:Content-Encoding: gzip 使用的时候,Transfer-Encoding: chunked还是比较有用的。
记得以前实现:Content-Encoding: gzip 输出时,先把整个压缩后的数据写到一个很大的字节数组里(如 ByteArrayOutputStream),然后得到数组大小 -> Content-Length。
如果结合Transfer-Encoding: chunked使用,就不必申请一个很大的字节数组了,可以一块一块的输出,更科学,占用资源更少。
这在http协议中也是个常见的字段,用于http传送过程的分块技术,原因是http服务器响应的报文长度经常是不可预测的,使用Content-length的实体搜捕并不是总是管用。
分块技术的意思是说,实体被分成许多的块,也就是应用层的数据,TCP在传送的过程中,不对它们做任何的解释,而是把应用层产生数据全部理解成二进制流,然后按照MSS的长度切成一分一分的,一股脑塞到tcp协议栈里面去,而具体这些二进制的数据如何做解释,需要应用层来完成,所以在这之前,一快整体应用层的数据需要等它分成的所有TCP segment到达对方,重新组装后,应用程序才使用自己的解码方法还原它们。
HTTP1.1采用了持久的连接,也就是一次TCP的连接不马上释放,允许许多的请求跟响应在一个TCP的连接上发送,所以客户机与服务器需要某种方式来标示一个报文在哪里结束和在下一个报文在哪里开始。简单的方法是使用呢content-length,但这只有当报文长度可以预先判断的时候才起作用,而对于动态的内容或者在发送数据前不能判定长度的情况下,可以使用分块的方法来传送编码。
通过 HttpURLConnection 远程拉一个30M的文件拉下来的文件比源文件小,看了一下response header里是ransfer-Encoding: chunked但不知道怎么解析,希望有大牛能提供...
http://blog.csdn.net/lhj_5460/article/details/48156461
public static byte[] chunked(InputStream in) throws Exception {
ByteArrayOutputStream tmpos = new ByteArrayOutputStream(4);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
int data = -1;
int[] aaa = new int[2];
byte[] aa = null;
while ((data = in.read()) >= 0) {
aaa[0] = aaa[1];
aaa[1] = data;
if (aaa[0] == 13 && aaa[1] == 10) {
aa = tmpos.toByteArray();
int num = 0;
try {
num = Integer.parseInt(new String(aa, 0, aa.length - 1)
.trim(), 16);
} catch (Exception e) {
System.out.println("aa.length:" + aa.length);
e.printStackTrace();
}
if (num == 0) {
in.read();
in.read();
return bytes.toByteArray();
}
aa = new byte[num];
int sj = 0, ydlen = num, ksind = 0;
while ((sj = (in.read(aa, ksind, ydlen))) < ydlen) {
ydlen -= sj;
ksind += sj;
}
bytes.write(aa);
in.read();
in.read();
tmpos.reset();
} else {
tmpos.write(data);
}
}
return tmpos.toByteArray();
}