关键词搜索

源码搜索 ×
×

文本文件utf-8 bom编码导致内容读取乱码和无法比较匹配

发布2019-12-05浏览1088次

详情内容

spring boot项目中,有些配置,我不愿意正正经经,规规矩矩地写一个配置实体类来读取,那样要写不少代码,颇费周折,就想简单地通过文件读取的方式,将内容读进来,然后解释、处理。于是用记事本创建了一个.txt文件。内容有汉字,读取出来之后,做一些查找、匹配操作(indexOf()),结果失败。
在这里插入图片描述
在这里插入图片描述
究其原因,首先我读取文件的时候,用的是“ISO-8859-1”编码,然后项目默认编码是“UTF-8”,所以读取出来,当然比较失败;但将读取内容转化成“UTF-8”时,第一行的结果仍然比较失败,而后面的则正常。最后发现,该配置文件的编码方式为"UTF-8 BOM",文件开头多了3个特殊字节,所以第一行就比较失败了。

UTF-8 BOM其实是一种特殊的UTF-8,跟UTF-8编码文件的唯一不同,是在文件开头加入了一个3字节的特殊标记,用于指定每个字对应的数据在内存地址中存放顺序,即俗称的大端小端。大端模式,数据的高字节保存在内存的低地址,而数据的低字节保存在内存的高地址中。小端模式则相反。但是,无BOM(byte-order mark,字节顺序)的UTF-8才是标准的,UTF-8里塞入一个BOM只是微软的习惯用法。也因此,这个文本文件qj.txt我在intellij idea里编辑,是纯的utf-8编码;用记事本打开,修改了一下,就变成utf-8 bom编码了。

由于BOM只在文件开头,所以第一行数据比较失败,后面的则正常。

读取代码如下:

//读取文件内容,返回由行组成的数组
private ArrayList _getAllQj(){
    ArrayList lines = new ArrayList();

    try{
        String path = ResourceUtils.getURL("classpath:").getPath();
        path = URLDecoder.decode(path, "utf-8");
        path = String.format("%s\\qj.txt",path);
        /*
        RandomAccessFile(),默认编码是用"ISO-8859-1"
        */
        RandomAccessFile raf = new RandomAccessFile(path, "r");//只读方式读文件
        String line = raf.readLine();
        while(line != null){
            lines.add(line);
            line = raf.readLine();
        }
        raf.close();
    } catch(Exception ex){

    }

    return lines;
}
//比较与匹配
public String getQj(String name) {
    String url = "";

    ArrayList lines = _getAllQj();//读取文件内容,返回由行组成的数组
    for(Object obj : lines){
        String line = obj.toString();
        String[] values = line.split(",");//侠客岛,http://localhost/quanjing/侠客岛全景/view.htm
        try {
        	/*
        		name2,表面上看值为“侠客岛”,但它前面多出了3个字节!导致后面的indexOf()失败
        	*/
            String name2 = new String(values[0].getBytes("ISO-8859-1"),"UTF-8");
            //name = “侠客岛管理委员会”
            if(name.indexOf(name2) >= 0) {//结果是false!
                url = values[1];
                break;
            }
        } catch(Exception ex){

        }
    }

    return (url.length() > 0) ? "redirect:" + url : url;
}
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

知道了问题所在就可以想好如何应对。可以将文件转回标准的utf-8编码,也可以在第一行写上不参与比较的注释,最好用英文,以避开这个雷区。

每当代码中需要用汉字来做配置或比较时,我都有点担心,担心在哪个环节不小心就会出问题。这编码那编码。这个问题,从20、30年前我接触电脑时就存在,到了今天,这个问题仍然是个坑,不小心就会掉进去。

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载