Java解析网络数据流的三种特殊方法

原文链接:http://www.yesky.com/180/1950680.shtml    

Java作为最开放的语言,已越来越受到网络程序员的青睐。但这一青睐族有着同样的经历——曾经都为网络上通

信的Java数据格式而烦脑。

  笔者也不例外,曾经为此而查阅了很多文档,经过反复测试才得以解决,如今笔者已经在所从事的很多电子政务

项目中顺利的应用。今天笔者写此文,介绍用Java解析网络数据的三种特殊方法,希望对正在寻求这方面问题答案的读者有所帮助。


  UTF8转换成GB2312 当我们在基于HTTP协议的JSP或Servlet的应用中获取数据或发送请求时,JVM会把输送的数据

编码成UTF8格式。如果我们直接从HTTP流中提取中文数据,提取的结果为“????”(可能更多问号),为转换成我们

能够理解的中文字符,我们需要把UTF8转换成GB2312,借助ISO-8859-1标准编码能够轻易的实现,下面的代码实现了这一功能: 


<span style="font-family:Microsoft YaHei;font-size:24px;"><span style="white-space:pre">	</span>byte [] b;
<span style="white-space:pre">	</span>String utf8_value; </span>
<span style="font-family:Microsoft YaHei;font-size:24px;"><span style="white-space:pre">
</span></span><pre name="code" class="java"><span style="font-family:Microsoft YaHei;font-size:24px;"><span style="white-space:pre">	</span>//从HTTP流中取"NAME"的UTF8数据</span>
utf8_value = request.getParameter("NAME");
 
<span style="font-family:Microsoft YaHei;font-size:24px;">
<span style="white-space:pre">	</span>b = utf8_value.getBytes("8859_1"); //中间用ISO-8859-1过渡
<span style="white-space:pre">	</span>String name = new String(b, "GB2312"); //转换成GB2312字符</span>



  在知道流长度的情况下将输入流转换成字节数组 Java中的输入流抽象类InputStream有int read(byte[] b,

 int off, int len)方法,参数中byte[] b是用来存放从InputStream中读取的数据,int off指定数组b的偏

移地址,也就是数组b的起始下标,int len指定需要读取的长度,方法返回实际读取的字节数。刚学Java的朋友

可能要说:先定义一个与流长度等长的字节数组,调用read方法,指定起始下标为0,指定读取长度与数组长度

等长,不是一下子可以读出来了吗?说的没错,笔者曾经也试着这样读取数据,但后来发现在读取网络数据时很

不安全,我们想想在网络上获取数据可能并没那么流畅,数据流的传送可能会断断续续,所以并不能保证一次就

能读取全部数据,特别是在读取大容量数据时更是如此,所以我们必须在读取数据时检测实际读到的长度,如果

没有读完已知长度的数据就应该再次读取,以此循环检测,直到实际读取的长度累加与已知的长度相等,下面的

代码实现了这一功能:


             
              
<span style="font-family:Microsoft YaHei;font-size:24px;"><span style="white-space:pre">	</span>ServletInputStream inStream = request.getInputStream(); //取HTTP请求流
<span style="white-space:pre">	</span>int size = request.getContentLength(); //取HTTP请求流长度
<span style="white-space:pre">	</span>byte[] buffer = new byte[size]; //用于缓存每次读取的数据
<span style="white-space:pre">	</span>byte[] in_b = new byte[size]; //用于存放结果的数组

<span style="white-space:pre">	</span>int count = 0;
<span style="white-space:pre">	</span>int rbyte = 0;
<span style="white-space:pre">	</span>while (count < size) { //循环读取
 <span style="white-space:pre">		</span>rbyte = inStream.read(buffer); //每次实际读取长度存于rbyte中
 <span style="white-space:pre">		</span>for(int i=0;i;)
  <span style="white-space:pre">			</span>in_b[count + i] = buffer[i];
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>count += rbyte;
}</span>



  在不知道流长度的情况下将输入流转换成字节数组 前面介绍了已知流长度的情况下的转换方法,那么当我们不知

道流有多长时,也就是说不能确定转换后的字节数组有多大时,该怎么处理呢?笔者查看了JDK文档之后发现

ByteArrayOutputStream有一个byte[] toByteArray()方法,该方法会自动创建一个字节数组,然后返回。于是就巧

妙的用ByteArrayOutputStream来作中间过渡实现转换,其它处理跟上面所介绍已知长度的情况差不多。假设需要被

转换的流已经放在inStream里了,我们可以用如下的代码实现这一功能:

<span style="font-family:Microsoft YaHei;font-size:24px;"><span style="white-space:pre">	</span>ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
<span style="white-space:pre">	</span>byte[] buff = new byte[100]; //buff用于存放循环读取的临时数据
<span style="white-space:pre">	</span>int rc = 0;
<span style="white-space:pre">	</span>while ((rc = inStream.read(buff, 0, 100)) > 0) {
 <span style="white-space:pre">		</span>swapStream.write(buff, 0, rc);
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>byte[] in_b = swapStream.toByteArray(); //in_b为转换之后的结果</span>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值