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

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

读取不连续的网络传输中的InputStream的相关文章

使用加密解密技术和CA认证解决网络传输中的安全隐患

服务端:xuegod63.cn   IP:192.168.1.63 客户端:xuegod64.cn   IP:192.168.1.64   网络安全: 网络传输中的安全隐患-.   中间人攻击 全隐患:        解决方法 1.窃听-- >  加密 2.篡改 ->  哈西算法:MD5,sha1 (检查数据完整性) 3.伪装(钩鱼网站,伪装WIFI)  ->  身份认证(用户名/密码.数字证书) 4.网络中断 (内网冒冲网关,DDOS )  –>绑定静态arp地址: 加大服务器和

Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)

MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明文是yanzi1225627,得到MD5加密后的字符串是:14F2AE15259E2C276A095E7394DA0CA9  但不能由后面一大串倒推出yanzi1225627.因此可以用来存储用户输入的密码在服务器上.现在下载文件校验文件是否中途被篡改也是用的它,原理参见:http://blog.c

(转载)详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表

郑重声明:原文转载于http://dengqi.blog.51cto.com/5685776/1223132 向好文章致敬!!! 一:MAC地址表详解 说到MAC地址表,就不得不说一下交换机的工作原理了,因为交换机是根据MAC地址表转发数据帧的.在交换机中有一张记录着局域网主机MAC地址与交换机接口的对应关系的表,交换机就是根据这张表负责将数据帧传输到指定的主机上的. 交换机的工作原理 交换机在接收到数据帧以后,首先.会记录数据帧中的源MAC地址和对应的接口到MAC表中,接着.会检查自己的MAC

网络传输中的三张表,MAC地址表、ARP缓存表以及路由表

一:MAC地址表详解 说到MAC地址表,就不得不说一下交换机的工作原理了,因为交换机是根据MAC地址表转发数据帧的.在交换机中有一张记录着局域网主机MAC地址与交换机接口的对应关系的表,交换机就是根据这张表负责将数据帧传输到指定的主机上的. 交换机的工作原理 交换机在接收到数据帧以后,首先.会记录数据帧中的源MAC地址和对应的接口到MAC表中,接着.会检查自己的MAC表中是否有数据帧中目标MAC地址的信息,如果有则会根据MAC表中记录的对应接口将数据帧发送出去(也就是单播),如果没有,则会将该数

IP协议和网络传输中的封装与分用。

关于七层模型和四层模型可以参考这个:http://www.cnblogs.com/xcywt/p/5027277.html 因为四层模型用的比较多,这里只拿四层模型来分析. 1.四层模型中的最下层是链路层,传输的是以太网数据帧.主要有三种格式的以太网数据帧.这里暂时不做详细分析 2.IP数据报格式 1)版本:IP协议版本号,IPv4版本这个值为4.IPv6这个值为6 2)头长度:表示头部的长度,单位是4字节.比如这个数为5,表示IP头部长度为20个字节.所以我们也可以知道IP长度最大为4x15

网络传输中TCP或者UDP是否畅通测试

在音视频开发和使用过程中,经常会遇到TCP或者UDP是否畅通的问题,现在根据市面上比较稳定的AnyChat平台,进度Demo的调试,为大家提供一个简单的测试方法. 首先下载AnyChat的软件,可以到他们的官网下载:www.anychat.cn 下载本人提供的附件工具:sockettool.rar(755.9 KB, 下载次数:177) 压缩包有使用说明,不具体表述. 现针对使用官方Demo时遇到的情况做简单的测试:测试服务器端和客户端的TCP或者UDP是否畅通. 首先服务器端操作如下: 打开s

ip 在网络传输中是如何传递的

前言 ip 我们知道有ip4与ip6.ip6还未实行,那么就暂且不谈. ip4我们在传递的时候一般是这样的"127.0.0.1",但是我们传输的是信号,也就是二进制数据,这个字符如何转换成2进制的? 把"127.0.0.1" 转换成一个什么形式的二进制? 主要的是一个约定,规定ip占用4个字节. 127 占用1个字节,0.0.1同样占用1个字节. 首先切割"127.0.0.1"为 127 0 0 1,且转换成整数. 如何把他们合成一个整数? 00

DICOM医学图像处理:DICOM网络传输

背景: 专栏取名为DICOM医学图像处理原因是:博主是从医学图像处理算法研究时开始接触DICOM协议的.当初认识有局限性,认为DICOM只是一个简单的文件格式约定,简而言之,我当时认为DICOM协议就是扩展名为DCM文件的格式说明.其实不然,随着对医疗行业的深入,对DICOM协议也有了更全面的认识.而今才发现DCM文件只是DICOM协议一部分中的一小节,仅仅是整个协议中的一个数据结构,而DICOM协议更多的是关于医疗行业各种服务及相关流程的约定,因此其实DICOM协议中最主要的是信息流,是对医院

如何在Android中播放网络传输过来的AAC音频?

============问题描述============ 如何在Android中播放网络传输过来的AAC音频?每个包都有ADTS头的. ============解决方案1============ 如果是应用的话,直接设置MediaPlayer setDataSource设置为网络音频的uri,然后prepareAsync(), prepare完成后调用start不就可以了吗? framework层的话还是要用aacdecoder进行解码播放,要么用软件解码,要么用硬件解码.