zoukankan      html  css  js  c++  java
  • 解码(ByteBuffer): CharsetDecoder.decode() 与 Charset.decode() 的不同

    今天测试的时候发现一个问题:

    ByteBuffer inputBuffer = ByteBuffer.allocate(1024);

    StringBuilder inputData = new StringBuilder(256);

    int size = sChannel.read(inputBuffer);

    Charset charset = Charset.forName("utf-8");
    CharsetDecoder decoder = charset.newDecoder();

    try
       {

    //如果用utf-8解码,抛java.nio.charset.MalformedInputException:Malformed input length is 1

    //如果用gbk解码,抛 java.nio.charset.MalformedInputException:Malformed input length is 2

    //抛异常的几率在5%左右,也就是说并不是每次都会抛异常
        inputData.append(decoder.decode(inputBuffer)); 

      }
       catch (CharacterCodingException err)
       {
        System.err.println("CharacterCodingException: " + new String(inputBuffer.array()));
        err.printStackTrace();
       }

    到百度搜索了一下,找到一篇:http://topic.csdn.net/u/20100310/17/4cf1c1a5-b01c-4774-a803-81ee245ae0eb.html

    主要内容:

    1. 这种现象是很正常的,由于网络上是一bit为单位传输,而TCP层上送的数据是以字节为单位,虽然NIO是以块为单位操作的,但是应用层处理时还是得以字节为单位处理。但是你使用的应该是ByteBuffer的派生类,(猜测是CharBuffer)它是以两个字节为单位处理报文的,因此很容易出现楼主的问题。

    解决方案:
    在处理数据之前,先判断ByteBuffer中的字节数,如果为奇数,则直接return false;不进行处理,等下一个消息来到时统一处理(注:可以这样做的原因是,这种现象是由于传输层上送的数据非完整应用层包) 2. 因为在GBK中字母占1byte汉字占2byte。ByteBuffer如果设置长度为偶数时,如果有奇数个字母那么最后的byte就是汉字的一部分,转码的时候就会出错。Bytebuffer设为奇数正好相反。可以判断ByteBuffer.get(index)大于0小于127的个数,然后确定最后一位是否要放到下次读入的第一位 3. 帖子的答案:“你是怎么处理数据包的,有处理粘包吗” ,粘包为何物? 再搜索,又找到一篇:http://www.blogjava.net/easywu/archive/2009/06/04/280100.html
    如果直接使用Charset.decode()方法,则不会出现这样的错误: private final static Charset charset = Charset.forName("UTF-8");
    inputData.append(charset.decode(inputBuffer).array()); //解码 改成这样后,再也不抛什么异常了,使用charset.decode()后,连异常都不需要捕获了。 经过测试,CharsetDecoder.decode() 与 Charset.decode() 的性能一样,通过查看API,charset类的所有方法都是线程安全的。     

    2012-06-10

    名品推荐:兰可欣 亚缇克兰 郁美净

  • 相关阅读:
    在opencv3中实现机器学习之:利用正态贝叶斯分类
    在opencv3中进行图片人脸检测
    在opencv3中利用SVM进行图像目标检测和分类
    在opencv3中实现机器学习之:利用svm(支持向量机)分类
    在matlab和opencv中分别实现稀疏表示
    opencv2学习:计算协方差矩阵
    用python简单处理图片(3):添加水印
    Google protocol buffer在windows下的编译
    GEOS库学习之五:与GDAL/OGR结合使用
    GEOS库学习之四:几何关系判断
  • 原文地址:https://www.cnblogs.com/personnel/p/4583259.html
Copyright © 2011-2022 走看看