曾遇到过这么一个问题,就是我想比较两个文件中有哪些是不一致的,但是发现用java代码跑出来的结果却令人大跌眼镜,出现了本来一样的字符串结果硬生生的给我打印出来不一样!比如1000-11-20190225-ZP-1551024000-1632240000这个字符串,放在两个文件,用java读取文件中的值并做比较,发现竟然不一样!!这让我当时百思不得其解,还以为是Eclipse或IDEA出现了问题呢。

我把我写的代码粘贴出来

@Test
public void testNotEqualData() throws IOException {File file=new File("F:\\stockSnapshot\\erp1.txt");BufferedReader reader=null;String temp=null;File file2=new File("F:\\stockSnapshot\\result1.txt");BufferedReader reader2=null;try{reader=new BufferedReader(new FileReader(file));List<String> list = new ArrayList<>();while((temp=reader.readLine())!=null){System.out.println("temp的长度:" + temp.length());list.add(temp);}reader2=new BufferedReader(new FileReader(file2));while((temp=reader2.readLine())!=null){System.out.println("temp2的长度:" + temp.length());if (!list.contains(temp)) {System.out.println("两边数据不一致的是:" + temp);}}}catch(Exception e){e.printStackTrace();}finally{if(reader!=null){try{reader.close();}catch(Exception e){e.printStackTrace();}}}
}

运行后的结果如下:

temp的长度:42
temp2的长度:41
两边数据不一致的是:1000-11-20190225-ZP-1551024000-1632240000

最后发现原来是两个文件的编码格式不太一样,一个是UTF8无BOM格式,一个是UTF8格式,这两种格式虽然都是UTF8,但还是有区别的,在Windows下用文本编辑器创建的文本文件,如果选择以UTF-8等Unicode格式保存,会在文件头(第一个字符)加入一个BOM标识(从第二行开始便没有这个BOM标识了)。

这个标识在Java读取文件的时候,不会被去掉,而且String.trim()也无法删除。如果用readLine()读取第一行存进String里面,这个String的length会比看到的大1(上面运行结果一个是42,一个是41),而且第一个字符就是这个BOM。

这种情况会给我们造成困扰,幸好,Java在读取Unicode文件的时候,会统一把BOM变成“\uFEFF”,这样的话,就可以自己手动解决了(判断后,用substring()或replace()去除掉这个BOM):

比如:temp = temp.trim().replaceAll("\\uFEFF", "");这样来统一去掉这个BOM。

但是这种解决方式不太好,如果生成jar文件在windows下运行,还是有问题,比较好的解决方式有两种:

第一种:把两个文件的编码格式都改为UTF-8无BOM格式,这样文件中的内容都不带BOM,从而也就没有我们说的这个问题了。

第二种:apache commons io提供的BOMInputStream

添加如下依赖:

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version>
</dependency>

然后使用下面的方式来读取文件中的内容(可以看到主要是用到了BOMInputStream这个类)

@Test
public void testNotEqualData() throws IOException {File file=new File("F:\\stockSnapshot\\erp1.txt");BufferedReader reader=null;String temp=null;File file2=new File("F:\\stockSnapshot\\result1.txt");BufferedReader reader2=null;try{//使用BOMInputStream自动去除UTF-8中的BOM!!reader = new BufferedReader(new InputStreamReader(new BOMInputStream(new FileInputStream(file))));List<String> list = new ArrayList<>();while((temp=reader.readLine())!=null){System.out.println("temp的长度:" + temp.length());list.add(temp);}reader2=new BufferedReader(new InputStreamReader(new BOMInputStream(new FileInputStream(file2))));while((temp=reader2.readLine())!=null){System.out.println("temp2的长度:" + temp.length());if (!list.contains(temp)) {System.out.println("两边数据不一致的是:" + temp);}}}catch(Exception e){e.printStackTrace();}finally{if(reader!=null){try{reader.close();}catch(Exception e){e.printStackTrace();}}}
}

修改后的运行结果如下:

temp的长度:41
temp2的长度:41

大家看具体情况,如果不允许修改文件的编码格式,那么第二种方式无疑是比较好的。

为何两个完全一样的字符串相比较却不一样相关推荐

  1. mysql 函数多个连接_MySQL数据库中如何连接两个或多个字符串呢?

    摘要: 下文讲述MySQL数据库中组合字符串的方法分享,如下所示: 实现思路: 使用系统函数CONCAT即可实现两个或多个字符串的组合连接 注意事项: 当组合字符串中,任意一个字符为NULL时,则返回 ...

  2. iOS获取自1970年毫秒数使用OC和swift两种语法,返回字符串

    iOS获取自1970年毫秒数使用OC和swift两种语法,返回字符串 oc的话,我们定义一个category分类,对谁分类,对NSDate分类,对外暴露一个类方法,只要导入头文件,即可使用. @int ...

  3. 《Java安全编码标准》一2.11 IDS10-J不要拆分两种数据结构中的字符串

    2.11 IDS10-J不要拆分两种数据结构中的字符串 在历史遗留系统中,常常假设字符串中的每一个字符使用8位(一个字节,Java中的byte).而Java语言使用16位表示一个字符(Java中的Ch ...

  4. “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。花花非常喜欢这种拥有对称美的回文串,生日的时候她得到两个礼物分别是字符串A和字符串B。

    1.题目描述 "回文串"是一个正读和反读都一样的字符串,比如"level"或者"noon"等等就是回文串. 花花非常喜欢这种拥有对称美的回文 ...

  5. java截取某两个字符之间的字串_Java截取特定两个标记之间的字符串实例

    Java截取特定两个标记之间的字符串实例 如有一串字符串: higklmnopq java代码如下: public class StringTest { public static void main ...

  6. JSON的两个方法(JSON转字符串和字符串转JSON)

    JSON的两个方法(JSON转字符串和字符串转JSON) //JSON javaScript Object Notation//JSON是一种数据格式 只要符合key:value 这种格式的都叫做JS ...

  7. oracle数据库 交集,Oracle两个逗号分割的字符串,获取交集、差集(sql实现过程解析)...

    Oracle数据库的两个字段值为逗号分割的字符串,例如:字段A值为"1,2,3,5",字段B为"2". 想获取两个字段的交集(相同值)2,获取两个字段的差集(差 ...

  8. .NET 5.0 RC1 发布,离正式版发布仅剩两个版本,与 netty 相比更具竞争力

    原文:http://dwz.win/Qf8 作者:Richard 翻译:精致码农-王亮 说明: 1. 本译文并不是完全逐句翻译的,存在部分语句我实在不知道如何翻译或组织就根据个人理解用自己的话表述了. ...

  9. 二进制数与十进制数相互转换 string陷阱(赋值错误) 汉字分为两个字符 string123 string字符串逆转

    二进制数与十进制数相互转换: 二进制数(数组)转换成十进制数的函数: BtoO(char str[]) { int lg,sum=0,j=1; lg=strlen(str)-1; for(;lg> ...

最新文章

  1. 多媒体计算机技术在教学中的应用,【浅谈多媒体计算机技术在中学物理教学中的应用】计算机技术是什么...
  2. 噪声对于训练神经网络的重要性
  3. Unity3D深入浅出 -组件与节点之间的调用关系
  4. 前端-----盒子模型
  5. 苹果公司推出新款iMac产品
  6. spring cloud学习进阶篇:Spring Cloud Sleuth + Zipkin 实现分布式跟踪解决方案
  7. 函数的二义性与函数对象的传递问题(通过实现vector的to_string示例)
  8. spark基础之调度器运行机制简述
  9. uiscrollview 图片放大缩小
  10. android MVC和MVP探讨
  11. 简述商业模式、商业模式画布与商业模式个人画布
  12. 地图的文字注记的制作和优化
  13. alsa mixer编程
  14. 马斯克搞的超级高铁,为什么注定会失败?
  15. Java开发一年经验北京薪资,全网首发!
  16. 立陶宛央行抢跑数字货币背后:前瞻的区块链战略 中国已有企业布局
  17. DNA序列编码中Hairpin的定义和计算
  18. selenium常用模块(传送门)
  19. STM32L0系列之【LPTIM定时器】
  20. 什么是强化学习?强化学习之父:它是人工智能的未来

热门文章

  1. python程序设计教学设计_Python教案 - 教学设计.doc
  2. 攻防世界MISC进阶之misc1
  3. 【C深入】程序中的三国天下,栈,堆,静态内存
  4. Android与uni-app 互相通信案例(包含源代码)
  5. 定义一个Tree(树)类,有成员ages(树龄),成员函数grow(int years)对ages加上years,age()显示tree对象的ages的值。
  6. 将像素绘制到屏幕上去
  7. Linux小技巧: nmtui ——(你们推)图形界面网卡编辑
  8. 【spring-boot】Could not find result map ‘com.springboot.cib_hk.bean.Users‘ referenced from ‘co...
  9. Oxford Nanopore MinION Sequencing and Genome Assembly
  10. 2022年天梯赛题目记录