中文系统下,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、读取第一行时,将编码信息去除即可

时间: 2024-08-11 09:42:58

中文系统下,UTF-8编码文本文件读取导致的错误的相关文章

配置 .vimrc 解决 Vim / gVim 在中文 Windows 下的字符编码问题

转载自:-杨博的日志 - 网易博客 Vim / gVim 在中文 Windows 下的字符编码有两个问题: 默认没有编码检测功能 如果一个文件本身采用的字符集比 GBK 大(如 UTF-8.UTF-16.GB18030),那么其中无法在 GBK 中对应的字符都会出现乱码,保存时会丢失.即使编辑文件时正确检测出文件格式也无济于事. 第一个问题的解决办法是在 ~/.vimrc 中加入以下配置: set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,eu

解决linux系统下因分区目录划分过小,导致tomcat使用系统临时文件夹(/tmp)没有足够空间而报错的问题

1. 故障现象. B/S应用进行文件上传后,系统反馈:没有足够的磁盘空间(No enough space available). 2. 故障分析 检查文件占用情况如下: [root@Qa2 /]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 6.7G 6.7G 20k 100% / devtmpfs 7.8G 0 7.8G 0% /dev tmpfs 7.8G 0 7.8G 0% /dev/sh

Linux系统下转换文件编码的方法

1.利用iconv命令进行文件内容编码转换      用法: iconv [选项...] [文件...] 有如下选项可用: 输入/输出格式规范:-f, --from-code=名称 原始文本编码-t, --to-code=名称 输出编码 信息:-l, --list 列举所有已知的字符集 输出控制:-c 从输出中忽略无效的字符-o, --output=FILE 输出文件-s, --silent 关闭警告--verbose 打印进度信息 -?, --help 给出该系统求助列表--usage 给出简

Windows系统下查看文件编码类型

这是一个程序员的最基本的技能,原谅我到现在才去了解 以前只知道window操作系统下文件大部分默认编码是ANSI,中文版是GBK编码 如果想要查看或者修改文件编码的话有两种方式 一:用记事本打开文件,另存为 可以查看,和修改文件编码 二:另一种就是通过工具喽,notepad++,程序员必备工具了 通过工具打开文件 默认选中的就是当前文件编码类型.这里你可以修改文件的编码,基本上我会使用encode in UTF-8 without BOM 这里,和UTF-8的具体区别,可以参考 http://w

linux系统下,11款常见远程桌面控制软件

linux系统下,11款常见远程桌面控制软件 一. Grdc 它是一个用GTK+编写的,适用于gnome桌面环境的远程桌面访问软件.看图: 常见功能: 1.提供全屏,窗口化的远程控制.支持高分辨率下的窗口显示以及调整. 2.可浮动的工具栏 3.可抓取键盘 4.支持建立一个“常用访问列表” 5.连接快速,高效 6.全屏模式下,当鼠标划过屏幕边缘时自动滚动 7.全屏模式下工具栏同样支持浮动效果,可直接进行例如模式切换,键盘抓取最小化等常见操作. 8. rdesktop 支持RDP协议, 9. 支持

ubuntu系统下,gsl 库链接问题 -undefined reference to `cblas_xxx`

今天在ubuntu系统下进行程序调试的时候出现以下错误信息: [ 10%] Linking CXX executable ../test_coco /usr/local/lib/libgsl.so: undefined reference to `cblas_ztrsv' /usr/local/lib/libgsl.so: undefined reference to `cblas_scasum' /usr/local/lib/libgsl.so: undefined reference to

英文字母和中文汉字在不同字符集编码下的字节数

英文字母和中文汉字在不同字符集编码下的字节数 英文字母: 字节数 : 1;编码:GB2312 字节数 : 1;编码:GBK 字节数 : 1;编码:GB18030 字节数 : 1;编码:ISO-8859-1 字节数 : 1;编码:UTF-8 字节数 : 4;编码:UTF-16 字节数 : 2;编码:UTF-16BE 字节数 : 2;编码:UTF-16LE 中文汉字: 字节数 : 2;编码:GB2312 字节数 : 2;编码:GBK 字节数 : 2;编码:GB18030 字节数 : 1;编码:ISO

CentOS系统下中文文件名乱码

原文来自:http://www.zhukun.net/archives/7434 CentOS系统下中文文件名乱码 2014/09/01Linux运维centos.Linuxbear 从windows上传到linux的文件或者目录,在Linux系统中显示为乱码.虽然将Linux的env设置了LANG=en_US.UTF-8,并且本地的Shell客户端编码也设置成UTF-8,但在Shell中(或通过http访问),仍是乱码…… 原因在于,Windows 的文件名中文编码默认为GBK,压缩或者上传后

mac系统下为emacs设置中文字体,解决乱码问题

最近换了个系统,现在用mac系统. 当打开emacs后,中文支持的不是很好.有的地方能显示,在.el文件的注释里显示为口口口口口口口口这样的框,如下图所示 找了半天,是因为中文字体的问题,只要设置好中文字体就行了. 以前在Linux下中文就支持的很好,不用配制中文字体就能显示. 配制代码如下(将其放到.emacs文件或init.el里就OK): ;; -------------------------------------------------------------------------