解码(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:\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() 的不同的更多相关文章
- 【Java nio】Channel
package com.slp.nio; import org.junit.Test; import java.io.*; import java.nio.ByteBuffer; import jav ...
- NIO与网络编程系统化学习
1.背景 数据在网络中传输,必然回遇到读写问题.... 2.比较NIO与IO 3.案例演示 3.1.缓冲区演示 package com.wfd360.nio; import org.junit.Tes ...
- 非阻塞模式ServerSocketChannel 聊天室服务器端
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import ja ...
- 遇到一道经典的java面试题
在文件 nameList.txt 中按下图格式存放着超过50万人的姓名与身份证信息.请使用您熟悉的编程语言(Java或C/C++)编写一段程序, 将出生日期落在1995年1月1日与1999年12月31 ...
- 中文数据解码报错 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 失败原因: ...
- Python中解码decode()与编码encode()与错误处理UnicodeDecodeError: 'gbk' codec can't decode byte 0xab
编码方法encoding() 描述 encode() 方法以指定的编码格式编码字符串,默认编码为 'utf-8'.将字符串由string类型变成bytes类型. 对应的解码方法:bytes decod ...
- python中------decode解码出现的0xca问题解决方法
一.错误: 解决方法: #源代码 data = sk.recv(1024) print(str(data,'gbk')) #修改代码 data = sk.recv(1024) print(str(da ...
- 字符编码和python .encode().decode()方法
字符编码与encode.decode的问题: 用8个开关表示世界万物 ASCII : American Standard Code for Information Interchange,美国 ...
- python encode decode unicode区别及用法
decode 解码 encode 转码 unicode是一种编码,具体可以百度搜 # coding: UTF-8 u = u'汉' print repr(u) # u'\u6c49' s = u.en ...
随机推荐
- 基于Nginx+Keepalived的LB服务监控(邮件报警)
IDC两台机器上部署了Nginx+Keepalived主从模式的LB代理负载层,现在需要对LB进行每日巡检和服务监控,利用SendEmail邮件监控. 0)SendEmail部署 参考:http:// ...
- CentOS7下安装Docker-Compose操作记录
Docker-Compose是一个部署多个容器的简单但是非常必要的工具.安装Docker-Compose之前,请先安装 python-pip 一.安装 python-pip [root@workben ...
- Gerrit日常维护记录
Gerrit代码审核工具是个好东西,尤其是在和Gitlab和Jenkins对接后,在代码控制方面有着无与伦比的优势. 在公司线上部署了一套Gerrit系统,在日常运维中,使用了很多gerrit命令,在 ...
- 牛客第二场-J-farm-二维树状数组
二维树状数组真的还挺神奇的,更新也很神奇,比如我要更新一个区域内的和,我们的更新操作是这样的 add(x1,y1,z); add(x2+1,y2+1,z); add(x1,y2+1,-z); add( ...
- What is 软件工程
话说新的一学期,有一门叫软件工程的专业课,作为计算机科学与技术专业的学生,在上课前有几个问题 1.软件工程顾名思义是学软件,可是软件这个词范围还是挺大的,那到底学的是哪方面,是编程?设计APP?还是一 ...
- keras-VGG16 猫狗分类器
keras 原理: keras系列︱图像多分类训练与利用bottleneck features进行微调(三)https://blog.csdn.net/sinat_26917383/article/d ...
- eclipse中git的author和commiter的修改
项目目录,隐藏的文件.git的文件夹,config文件 eclipse-->右击项目--showin--system explorer.git 打开config文件加上 [user] name ...
- github学习步骤
组员1: 王文政 201303011159 作业网址 :https://github.com/1246251747/3/blob/master/jjj.txt 心得: 1. 申请gi ...
- Daily Scrum 12.8
Member Task on 12.08 Task on 12.09 仇栋民 参与M2阶段第二次决策会议 开始Task964 : 活动评论功能雏形 康家华 开始Task982 : 完成活动界面的设计稿 ...
- Maven的课堂笔记2
5 maven的核心概念 5.1 项目对象模型 说明: maven根据pom.xml文件,把它转化成项目对象模型(POM),这个时候要解析依赖关系,然后去相对应的maven库中查找到依赖的jar包. ...