这是我在尝试用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); ...
时间: 2024-12-08 06:54:34