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

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:\n" + 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

解码(ByteBuffer): CharsetDecoder.decode() 与 Charset.decode() 的不同的更多相关文章

  1. 【Java nio】Channel

    package com.slp.nio; import org.junit.Test; import java.io.*; import java.nio.ByteBuffer; import jav ...

  2. NIO与网络编程系统化学习

    1.背景 数据在网络中传输,必然回遇到读写问题.... 2.比较NIO与IO 3.案例演示 3.1.缓冲区演示 package com.wfd360.nio; import org.junit.Tes ...

  3. 非阻塞模式ServerSocketChannel 聊天室服务器端

    import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import ja ...

  4. 遇到一道经典的java面试题

    在文件 nameList.txt 中按下图格式存放着超过50万人的姓名与身份证信息.请使用您熟悉的编程语言(Java或C/C++)编写一段程序, 将出生日期落在1995年1月1日与1999年12月31 ...

  5. 中文数据解码报错 UnicodeDecodeError: 'gbk' codec can't decode bytes in position 2-3: illegal multibyte sequence

    UnicodeDecodeError: 'gbk' codec can't decode bytes in position 2-3: illegal multibyte sequence 失败原因: ...

  6. Python中解码decode()与编码encode()与错误处理UnicodeDecodeError: 'gbk' codec can't decode byte 0xab

    编码方法encoding() 描述 encode() 方法以指定的编码格式编码字符串,默认编码为 'utf-8'.将字符串由string类型变成bytes类型. 对应的解码方法:bytes decod ...

  7. python中------decode解码出现的0xca问题解决方法

    一.错误: 解决方法: #源代码 data = sk.recv(1024) print(str(data,'gbk')) #修改代码 data = sk.recv(1024) print(str(da ...

  8. 字符编码和python .encode().decode()方法

    字符编码与encode.decode的问题:  用8个开关表示世界万物   ASCII :  American Standard Code for Information Interchange,美国 ...

  9. python encode decode unicode区别及用法

    decode 解码 encode 转码 unicode是一种编码,具体可以百度搜 # coding: UTF-8 u = u'汉' print repr(u) # u'\u6c49' s = u.en ...

随机推荐

  1. Jvm远程监控

    服务器运行新建文件 : udi.policy grant codebase "file:${java.home}/../lib/tools.jar" { permission ja ...

  2. linux书籍

    <鸟哥私房菜-基础版> <实战LINUX_SHELL编程与服务器管理> <LINUX命令行与SHELL脚本编程大全第2版].布卢姆.扫描版> <Linux初学 ...

  3. js 时间戳转换为日期格式

     //将1525854409000类型的时间转换成“yyyy-MM-dd”或“yyyy-MM-dd hh:mm:ss”   //info.birthday是后台获取到的Date类型的出生日期数据, / ...

  4. SCRUM 12.20

    以下为我们爬虫遇到问题的报告 我们团队的m2阶段原本计划是爬取美团的信息以支持我们的app对比功能,但在这一阶段遇到很多问题,主要表现如下: 美团反爬机制: 由于我们团队人员在事先并不知道美团具有反爬 ...

  5. Python学习笔记 -- 第五章

    模块 使用模块可以提高了代码的可维护性.其次,编写代码不必从零开始.当一个模块编写完毕,就可以被其他地方引用.我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块: ...

  6. java中字符串的排序(1)

    按照前段时间在快速.冒泡等排序的评论中提到是否可以进行字符串的排序,由于最近有考试,时间比较紧,所以今天才实现此功能.此功能是针对一串字符川进行的实现,运行后的结果如下所示: 具体的程序相对较为简单, ...

  7. 用Axios Element 实现全局的请求 loading

        Kapture 2018-06-07 at 14.57.40.gif demo in github 背景 业务需求是这样子的,每当发请求到后端时就触发一个全屏的 loading,多个请求合并为 ...

  8. CentOS7.5下MYSQL8.0.11

    MYsql的安装 1. 下载bundles 包 https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.11-1.el7.x86_64.rpm-bun ...

  9. hive-site.xml

    https://cwiki.apache.org/confluence/display/Hive/AdminManual+MetastoreAdmin#AdminManualMetastoreAdmi ...

  10. python数据相关性分析 (计算相关系数)

    #-*- coding: utf-8 -*- #餐饮销量数据相关性分析 计算相关系数 from __future__ import print_function import pandas as pd ...