中文系统下,UTF-8编码文本文件读取导致的错误
一、UTF-8编码文件读取导致的错误
有个txt文件,里面内容为:
aaa
bbb
ccc
以UTF-8编码方式打开txt文件,顺序读取,将里面的值放到一个hashset中,并判断aaa是否在在hashset中
class
{
public static void main(String[] args)
{
try
{
HashSet<String> specialCateSet= new HashSet<String>();
FileInputStream a = new FileInputStream("d://test.txt");
String encoding = "UTF-8";
InputStreamReader b = new InputStreamReader(a,encoding);
BufferedReader br = new BufferedReader(b); String message = br.readLine();
while (message != null)
{
specialCateSet.add(message);
message = br.readLine();
}
}
catch(Exception e)
{
e.printStackTrace();
} if(specialCateSet.contains("aaa"))
{
System.out.println("SpecialCate包含aaa");
}
else
{
System.out.println("SpecialCate不包含aaa");
}
}
}
结果输出:SpecialCateSet不包含aaa
断点跟踪SpecialCateSet中的值,里面确实包含值"aaa",但是为什么specialCateSet.contains("aaa")验证为false呢?
二、错误原因
中文操作系统下,对于UTF-8编码格式的文本文件,其前3个字节的值就是-17、-69、-65(这三个字节说明了编码方式,详情参考Java如何获取文件编码格式)
修改程序如下,就直观了:
class
{
public static void main(String[] args)
{
try
{
HashSet<String> specialCateSet= new HashSet<String>();
FileInputStream a = new FileInputStream("d://test.txt");
String encoding = "UTF-8";
InputStreamReader b = new InputStreamReader(a,encoding);
BufferedReader br = new BufferedReader(b); String message = br.readLine();
while (message != null)
{
//打印输出message的byte值
byte[] a1=message.getBytes();
for(byte b1 :a1){
System.out.print(b1+ " ");
}
System.out.println();
specialCateSet.add(message);
message = br.readLine();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
结果输出如下,其中a的ascll为97,b:98,c:99
-17 69 65 97 97 97
98 98 98
99 99 99
因此specialCateSet中存放三个字符串值aaa(byte字节为:-17 69 65 97 97 97),bbb(byte字节为:-98 98 98),ccc(byte字节为:-99 99 99),其中虽然在java中显示specialCateSet包含字符串aaa,但是这个字符串aaa的byte字节为(-17 69 65 97 97 97),而在后面判断中specialCateSet.contains("aaa"),在java中定义的aaa byte字节为(97 97 97),因此验证不通过。
通俗来讲,文本文件中读取的aaa的byte字节为(-17 69 65 97 97 97),其中包含有3个byte的编码值,但是在java中显示时将头三位的编码值忽略了,因此在java中显示的值为aaa,而直接在java中定义的字符串aaa的byte字节为(97 97 97),两者虽然显示一致,但是对应的字节值不同,以及各自的hashcode值也不同,因此java判断此aaa不同于彼aaa
三、解决办法
1、最简单的,在txt中空出第一行不用即可,因为就头三位是编码信息
2、读取第一行时,将编码信息去除即可
中文系统下,UTF-8编码文本文件读取导致的错误的更多相关文章
- 配置 .vimrc 解决 Vim / gVim 在中文 Windows 下的字符编码问题
转载自:-杨博的日志 - 网易博客 Vim / gVim 在中文 Windows 下的字符编码有两个问题: 默认没有编码检测功能 如果一个文件本身采用的字符集比 GBK 大(如 UTF-8.UTF-1 ...
- C#在 64位系统下出现 “未能加载文件或程序集”错误
64位系统下,Build的时候,如果选择Any CPU,默认会按照64位进行编译,便无法加载某些旧的dll,这些dll可能是特定到X86 CPU的. 所以,把编译选项中改为 X86CPU,就可以运行了 ...
- Windows系统下查看文件编码类型
这是一个程序员的最基本的技能,原谅我到现在才去了解 以前只知道window操作系统下文件大部分默认编码是ANSI,中文版是GBK编码 如果想要查看或者修改文件编码的话有两种方式 一:用记事本打开文件, ...
- vss 日文文件路径的名字在中文系统下乱码
解决方式:tools-font 文字设置 日本語
- 中文Win7下成功安装calabash-android步骤
Calabash-android是支持android的UI自动化测试框架,网上看见很多同学说,安装calabash比较费劲,特别是Windows下安装,也没有一个详细的安装手册可供参考.正好,今天在W ...
- linux系统下,11款常见远程桌面控制软件
linux系统下,11款常见远程桌面控制软件 一. Grdc 它是一个用GTK+编写的,适用于gnome桌面环境的远程桌面访问软件.看图: 常见功能: 1.提供全屏,窗口化的远程控制.支持高分辨率下的 ...
- linux系统下,11款常见远程桌面控制软件(转载)
远程控制能够给人们带来很多便利,本文介绍了11款常见的Linux系统下的远程桌面控制工具,总有一款能适合您. 一. Grdc 它是一个用GTK+编写的,适用于gnome桌面环境的远程桌面访问软件.看图 ...
- ubuntu系统下,gsl 库链接问题 -undefined reference to `cblas_xxx`
今天在ubuntu系统下进行程序调试的时候出现以下错误信息: [ %] Linking CXX executable ../test_coco /usr/local/lib/libgsl.so: un ...
- CentOS系统下中文文件名乱码
原文来自:http://www.zhukun.net/archives/7434 CentOS系统下中文文件名乱码 2014/09/01Linux运维centos.Linuxbear 从windows ...
随机推荐
- 08-Java 多线程编程
1.Java多线程-线程与进程的区别 (1)线程:程序中单独依靠程序进行运行 线程是程序中的顺序控制流,只能使用分配给程序的资源和环境. (2)进程:执行中的程序 一个进程可以包含一个或多个线程. 一 ...
- gridview+checkbox的各种操作【转】
来源:http://hi.baidu.com/heavensxq/item/29736dcfbdc30403c710b2b1 1.首先如何在gridview中加入一个checkbox,注意不是chec ...
- wikioi 1076 排序 【这里含冒泡、选择、插入以及快排库函数的调用】
/*=================================================================== 1076 排序 题目描述 Description 给出n和n ...
- angular.element方法汇总以及AngularJS 动态添加元素和删除元素
addClass()-为每个匹配的元素添加指定的样式类名after()-在匹配元素集合中的每个元素后面插入参数所指定的内容,作为其兄弟节点append()-在每个匹配元素里面的末尾处插入参数内容att ...
- tagName和nodeName的区别
首先介绍DOM里常见的三种节点类型(总共有12种,如docment):元素节点,属性节点以及文本节点,例如<h2 class="title">head</h2 ...
- jquery事件切换hover/toggle
1.hover([over,]out) 一个模仿悬停事件(鼠标移动到一个对象上面及移出这个对象)的方法.这是一个自定义的方法,它为频繁使用的任务提供了一种“保持在其中”的状态. 当鼠标移动到一个匹配的 ...
- apache反向代理 负载均衡
开启模块: LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so LoadModule slotmem_sh ...
- oracle的listener.ora sqlnet.ora tnsnames.ora三个文件的关联性
学习:http://www.cnblogs.com/william-lee/archive/2010/10/20/1856261.html 之前因为安装的是windows server 2008 r2 ...
- 在Ext JS 5应用程序中如何使用路由
简介 Ext JS 5是一个重要的发布版本,它提供了许多新特性来创建丰富的.企业级的Web应用程序.MVVM和双向数据绑定为开发人员承担了大量的繁重工作.在Ext JS 5种,另一个新特性就是路由,它 ...
- 利用百度地图API,获取经纬度坐标
利用百度地图API,获取经纬度坐标 代码很简单,但在网上没找到现成的获取地图经纬度的页面. 就是想,给当前页面传递一个经纬度,自动定位到此经纬度.然后可以重新选择,选择完返回经纬度. 效果如下: 源代 ...