码迷,mamicode.com
首页 > 其他好文 > 详细

读取不连续的网络传输中的InputStream

时间:2016-04-16 21:27:11      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

这是我在尝试用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);
              ...

读取不连续的网络传输中的InputStream

标签:

原文地址:http://www.cnblogs.com/wqbill/p/5399220.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!