我的Java开发学习之旅------>Java NIO 报java.nio.charset.MalformedInputException: Input length = 1异常
java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:260)
at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:781)
at cn.fuxi.nio.ReadFile.main(ReadFile.java:37)
具体的Java源代码如下:ReadFile.java
public class ReadFile {
public static void main(String[] args) {
FileInputStream fis;
try {
fis = new FileInputStream("a.txt");
FileChannel channel = fis.getChannel();
// 定义一个ByteBuffer,用于重复读取数据
ByteBuffer byteBuffe = ByteBuffer.allocate(64);// 每次取出64字节
// 将FileChannel的数据放入ByteBuffer中
while (channel.read(byteBuffe) != -1) {
// 锁定ByteBuffer的空白区
byteBuffe.flip();
/* 创建Charset对象 */
Charset charset = Charset.forName("GBK");
// 创建解码器
CharsetDecoder charsetDecoder = charset.newDecoder();
// 将ByteBuffer的内容转码
CharBuffer charBuffer = charsetDecoder.decode(byteBuffe);
// CharBuffer charBuffer = charset.decode(byteBuffe);
System.out.println(charBuffer);
// 将ByteBuffer初始化,为下一次读取数据做准备
byteBuffe.clear();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
This is just test for FileChannel 小心会报异常:java.nio.charset.MalformedInputException: Input length = 1,看到底是什么鬼原因弄成的。
说白了,会出现java.nio.charset.MalformedInputException异常,原因是“半个中文问题”。分析上面的程序,就是因为CharsetDecoder对ByteBuffer进行解码的时候,不能保证都可以成功解码成汉字,也许里面有“半个汉字“也说不准。说以当有半个汉字的时候就会出现该异常。
举个例子,因为在GBK中字母占1byte,汉字占2byte。如"我ABC汉字d"这个字符串,截取5个字节的时候,应该是"我ABC",而截取8个字节的时候,应该是"我ABC汉",而不应该是"我ABC汉?",其中"?"为半个汉字,可理解为向前截取 。所以就会报异常。 (备注:将字符编码GBK改为UTF-8,则每个中文长度按3个字符计算 )
byteBuffe = ByteBuffer.allocate(1024);
/* 创建Charset对象 */
Charset charset = Charset.forName("GBK");
// 创建解码器
CharsetDecoder charsetDecoder = charset.newDecoder();
// 将ByteBuffer的内容转码
// CharBuffer charBuffer = charsetDecoder.decode(byteBuffe);
改为:
/* 创建Charset对象 */
Charset charset = Charset.forName("GBK");
CharBuffer charBuffer = charset.decode(byteBuffe);
但是这样改掉之后,也会出现下面的乱码问题,所以也不提倡。
This is just test for FileChannel
小心会报异常:java.nio.charset.MalformedInputException: Input length = 1,看到底是什么鬼原因弄成的。
This is just test for FileChannel
小心会报异常:java.nio.charset.MalformedInputException: Input length = 1,看到底?
鞘裁垂碓蚺傻摹?
第三个解决方法:每次都去判断一下Bytebuffer中最后一个字节是否合法。如果不合法,则说明这个字节是双字节汉字的一部分,这样我们解码时就不要包含这个字节,而是把这个字节放进下次解码之前的Bytebuffer中。这样做,系统就不会抛出“无法正确解码”这类的异常了。
http://songjianyong.iteye.com/blog/1399241 寻找思路)
public class FileChannelTest {
public static void main(String[] args) {
try {
File file=new File("abc.txt");
//以文件输入流FileInputStream创建FileChannel,以控制输入
FileChannel inChannel=new FileInputStream(file).getChannel();
//以文件输出流FileOutputStream创建FileChannel,以控制输出
FileChannel outChannel=new FileOutputStream("a.txt").getChannel();
//将FileChannel里的全部数据映射成ByteBuffer
MappedByteBuffer buffer=inChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
//直接将buffer里的数据全部输出
outChannel.write(buffer);
//再次调用buffer的clear()方法,复原limit、position的位置
buffer.clear();
//使用GBK字符集来创建解码器
Charset charset=Charset.forName("GBK");
//创建解码器(CharsetDecoder)对象
CharsetDecoder decoder=charset.newDecoder();
//使用解码器将ByteBuffer转换成CharBuffer
CharBuffer charBuffer=decoder.decode(buffer);
System.out.println(charBuffer);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
哎,忙了一个晚上,还是没有真正的解决java.nio.charset.MalformedInputException: Input length = 1异常,惭愧。如果有大神来帮我解决解决,感激不尽。
==================================================================================================
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng
==================================================================================================
我的Java开发学习之旅------>Java NIO 报java.nio.charset.MalformedInputException: Input length = 1异常的更多相关文章
- 我的Java开发学习之旅------>工具类:Java使用正则表达式分离出字符串中的中文和英文
今天看到一个工具类使用正则表达式将一大段字符串中的中文和英文都分离出来了,在此记录一下,读者可以收藏! import java.util.ArrayList; import java.util.Col ...
- 我的Java开发学习之旅------>工具类:Java获取字符串和文件进行MD5值
ps:这几天本人用百度云盘秒传了几部大片到云盘上,几个G的文件瞬秒竟然显示"上传成功"!这真让我目瞪口呆,要是这样的话,那得多快的网速,这绝对是不可能的,也许这仅是个假象.百度了一 ...
- 我的Java开发学习之旅------>Java 格式化类(java.util.Formatter)基本用法
本文参考: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html http://www.blogjava.net/ ...
- 我的Java开发学习之旅------>工具类:将播放器的进度值转换成相应的时间格式
在我的博客<我的Java开发学习之旅------>Java 格式化类(java.util.Formatter)基本用法,地址:http://blog.csdn.net/ouyang_pen ...
- org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
项目启动报错2018-12-21 14:06:24.917 INFO 23472 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refr ...
- scala文件读取报错“java.nio.charset.MalformedInputException: Input length = 1”
今天写spark程序的时候遇到了一个问题就是,读取文件的时候报了一个错:“Exception in thread "main" java.nio.charset.Malformed ...
- protobuf接口调用报错:java.nio.charset.MalformedInputException: Input length = 1
使用protobuf定义的接口api发起http请求报错,日志如下: [-- ::] DEBUG AbstractPool: - server updated, node=, server={ nod ...
- windows中文编码报错 com.google.gson.JsonIOException: java.nio.charset.MalformedInputException: Input length = 1
昨天碰到一个问题:同一个请求页面,页面经过匹配后调用http的post协议接口,部署在linux环境的没问题,本地Eclipse启动的tomcat也没问题,直接启动本地tomcat却报错了: 18:4 ...
- Caused by: java.nio.charset.MalformedInputException: Input length = 1
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/applicatio ...
随机推荐
- 执行 innerHTML 里的 <script>
原文:执行 innerHTML 里的 <script> 背景 有时候我们会有把一整段 HTML 动态塞进页面的需求,例如渲染了一个模板,从服务器端获取了一段广告代码等.一般情况下我们使用 ...
- Android 分享透明图片到微信变黑的问题
/** * bitmap中的透明色用白色替换 * * @param bitmap * @return */ public static Bitmap changeColor(Bitmap bitmap ...
- android wifi 调试
(一)root你的Android(相信绝大多数人现在的手机已经ROOT了.(二)下载app: adbWireless,并安装到手机上.(三)安装adb工具包,其实,要在windows下使用ADB工具, ...
- linuxshell编程之变量
变量分类: 用户自定义变量:局部变量 定义格式:变量名=变量值(*等号左右不能有空格,加了空格会报错) 调用格式:echo $变量名(调用的是变量名等效的值) 变量叠加:$x=123,y=" ...
- 转:Java 自动装箱与拆箱(Autoboxing and unboxing)
转: http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing) ...
- beforeRouteLeave 实现vue路由拦截浏览器的需求,进行一系列操作 草稿保存等等
场景:为了防止用户失误点错关闭按钮等等,导致没有保存已输入的信息(关键信息).用法://在路由组件中: beforeRouteLeave (to, from, next) { if(用户已经输入信息) ...
- linux设备驱动程序之并发和竞态(二)
事实上这blog都是阅读ldd3时的一些总结,巩固自己的学习.也方便后期的使用.大家也能够直接阅读ldd3原文. 锁陷阱 所谓的锁陷阱就是防止死锁. 不明白的规则: ...
- libGDX 模块概览
本文章翻译自libGDX官方wiki,.转载请注明出处:http://blog.csdn.net/kent_todo/article/details/37940595 libGDX官方网址:http: ...
- 目标主体名称不正确,无法生成 SSPI 上下文。
参考地址:http://blog.csdn.net/burgess_liu/article/details/18300959 两个命令:setspn -L Server03 和 setspn -D S ...
- Oracle Sequence用plsql修改
在plsql中,打开Objects窗口 找Sequences文件夹>你需要修改的Sequence 选中你需要修改的sequence,右键edit(编辑) OK!