标签:
这是我在尝试用HttpURLConnection遇到的一个小插曲
String urltext = "http://???.?????.com/";
try {
URL url = new URL(urltext);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis=new BufferedInputStream(is);
// System.out.println(bis.available());
// 网络环境下bis.available并非全部
int count=0;
int sumcount=0;
ArrayList li=new ArrayList();
while((count=bis.available())!=0){
byte[] tmpbytes = new byte[count];
bis.read(tmpbytes);
li.add(tmpbytes);
sumcount+=count;
Thread.sleep(200);
}
System.out.println(sumcount);
...
最开始以为简单的使用available获取的长度作为总长度,事实上,数据过大时网络传输会分包进行,一个包若干字节,available就只是当前包字节数。
然后尝试循环读取available,直到为0,但是这里读的速度又普遍比网络传输的速度快,可能读了1-2个包下个包并没有传输过来,于是availble为0跳出循环,最后只好用每次线程暂停0.2s。
过了几天想了想又改成了下面所示代码
String urltext = "http://???.?????.???";
try {
URL url = new URL(urltext);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
int sumcount = 0;
int count=0;
ArrayList<Byte> li = new ArrayList<Byte>();
byte[] tmpbytes=new byte[1024];
while ((count=bis.read(tmpbytes)) != -1) {
for (int i = 0; i < count; i++) {
li.add(tmpbytes[i]);
}
sumcount += count;
}
System.out.println(sumcount);
int i = 0;
byte[] str = new byte[sumcount];
for (Object b : li) {
str[i]=(byte)b;
i++;
}
String json = new String(str);
...
这次就不用available构建数组,每次尝试读1024长度,注意是尝试,实际长度加到总长度中,实际字节存储起来,最后构建sumcount长度的byte数组。
不过因为要存不固定数量的byte值,用了ArrayList存储封装的Byte,感觉频繁创建大量对象开销比较大,暂时没有想到解决方案。
然后想到了StringBuffer中肯定有个动态增长的char数组,于是看了下源码,初始长度16的char[],一旦用满就扩展,长度为原来2倍+2(如果超过int范围就是负数则长度取int最大值),用Arrays.copyOf赋给新数组,再底层就是System的native方法,暂时还是没那个能力和精力去研究dll。
相似的ArrayList中grow()增量为50%,>>为右位移。Vector默认(无参构造)是原来2倍。
于是这里最终也改为Arrays.copyOf()。
String urltext = "http://???.?????.???";
try {
URL url = new URL(urltext);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
int sumcount = 0;
int count=0;
byte[] str = new byte[1024];
byte[] tmpbytes=new byte[1024];
while ((count=bis.read(tmpbytes)) != -1) {
str=Arrays.copyOf(str, sumcount+count);
for (int i = 0; i < count; i++) {
str[sumcount+i]=tmpbytes[i];
}
sumcount += count;
}
System.out.println(sumcount+":"+str.length);
...
标签:
原文地址:http://www.cnblogs.com/wqbill/p/5399220.html