原因:
关于utf-8编码的txt文件,windows以记事本方式保存时会在第一行最开始处自动加入bom格式的相关信息,大概三个字节!
所以java在读取此类文件时第一行时会多出三个不相关的字节,这样对正常的程序产生了不良影响!
解决方法:
网上有如下解决方法确实可行
1.使用UltraEdit将上边的txt文件另存为UTF-8无BOM格式;
2.使用Notepad++打开上边的txt文件执行如下操作“格式-->以UTF-8无BOM格式编码”,修改后将txt文本进行保存
不足之处:
但是这样也有不足,这样对文件生产者提出了很高的要求,万一这样的文件是很多人生产的,那就势必会产生各种各样的问题,这归根到底是jdk的一个bug.
有没有什么办法能够一劳永逸呢,答案是有的,咱们程序里控制,来跟着我一起做!
终极解决方案:
(1)在工程中增加JDK提供的一个工具类:
public class UnicodeInputStream extends InputStream {
PushbackInputStream internalIn;
boolean isInited = false;
String defaultEnc;
String encoding;
private static final int BOM_SIZE = 4;
public UnicodeInputStream(InputStream in, String defaultEnc) {
internalIn = new PushbackInputStream(in, BOM_SIZE);
this.defaultEnc = defaultEnc;
}
public String getDefaultEncoding() {
return defaultEnc;
}
public String getEncoding() {
if (!isInited) {
try {
init();
} catch (IOException ex) {
IllegalStateException ise = new IllegalStateException("Init method failed.");
ise.initCause(ise);
throw ise;
}
}
return encoding;
}
/**
* Read-ahead four bytes and check for BOM marks. Extra bytes are
* unread back to the stream, only BOM bytes are skipped.
*/
protected void init() throws IOException {
if (isInited) return;
byte bom[] = new byte[BOM_SIZE];
int n, unread;
n = internalIn.read(bom, 0, bom.length);
if ( (bom[0] == (byte)0x00) && (bom[1] == (byte)0x00) &&
(bom[2] == (byte)0xFE) && (bom[3] == (byte)0xFF) ) {
encoding = "UTF-32BE";
unread = n - 4;
} else if ( (bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE) &&
(bom[2] == (byte)0x00) && (bom[3] == (byte)0x00) ) {
encoding = "UTF-32LE";
unread = n - 4;
} else if ( (bom[0] == (byte)0xEF) && (bom[1] == (byte)0xBB) &&
(bom[2] == (byte)0xBF) ) {
encoding = "UTF-8";
unread = n - 3;
} else if ( (bom[0] == (byte)0xFE) && (bom[1] == (byte)0xFF) ) {
encoding = "UTF-16BE";
unread = n - 2;
} else if ( (bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE) ) {
encoding = "UTF-16LE";
unread = n - 2;
} else {
// Unicode BOM mark not found, unread all bytes
encoding = defaultEnc;
unread = n;
}
//System.out.println("read=" + n + ", unread=" + unread);
if (unread > 0) internalIn.unread(bom, (n - unread), unread);
isInited = true;
}
public void close() throws IOException {
//init();
isInited = true;
internalIn.close();
}
public int read() throws IOException {
//init();
isInited = true;
return internalIn.read();
}
}
(2)读取时使用如下代码: //因为我这边是服务器上的远程文件,如果是本地文件使用File类
URL url = new URL("http://****/***/test.txt");
// File f = new File("test.txt");
String enc = null; // or NULL to use systemdefault
UnicodeInputStream uin = new UnicodeInputStream(url.openStream(),enc); //如果是本地将url.openStream -> new FileInputStream(f)
enc = uin.getEncoding(); // check and skip possible BOM bytes
InputStreamReader in;
if (enc == null){
in = new InputStreamReader(uin);
}else {
in = new InputStreamReader(uin, enc);
}
BufferedReader reader = new BufferedReader(in);
//BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("D:/tags.txt"),"utf-8"));
String tmp =reader.readLine();
这样读取的结果就是正常的了,有什么问题还可以留言!
Java读带有BOM的UTF-8文件乱码原因及解决方法的更多相关文章
-
Java读取UTF-8格式文件第一行出现乱码——问号“?”及解决 And Java读带有BOM的UTF-8文件乱码原因及解决方法
測试样例: Java读取UTF-8的txt文件第一行出现乱码"?"及解决 test.txt文件内容: 1 00:00:06,000 --> 00:00:06,010 < ...
-
R读取excel文件乱码 read.xlsx() 解决方法
1. 参考[R语言]R读取含中文excel文件,read.xlsx乱码问题 该文章总结得很好,可以直接跳到最后看博主的总结. 2. 如果依旧是乱码那么用read.xlsx2()去读取excel文件, ...
-
/var/spool/clientmqueue目录下存在大量文件的原因及解决方法
问题现象:linux操作系统中的/var/spool/clientmqueue/目录下存在大量文件.原因分析: 系统中有用户开启了cron,而cron中执行的程序有输出内容,输出内容会以邮件形式发给c ...
-
Java并发--ConcurrentModificationException(并发修改异常)异常原因和解决方法
在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.util.ConcurrentModificationException异常.下面我们就来讨论 ...
-
og4j日志文件乱码问题的解决方法
现象:在默认语言非中文(或者说默认语言不支持中文的)的Windows.Linux.Unix上,用log4j打印日志,出现乱码,常见的就是一堆问号. 解决方法: 如果是log4j.properties为 ...
-
log4j日志文件乱码问题的解决方法
近日在AIX上用log4j打印日志,出现乱码,经过努力解决问题. 症状:在默认语言非中文(或者说默认语言不支持中文的)的Windows.Linux.Unix上,用log4j打印日志,出现乱码,常见的就 ...
-
Java Web乱码原因与解决
Java Web乱码原因与解决 一.了解编码常识: 1.ASCII 码 众所周知,这是最简单的编码.它总共可以表示128个字符,0~31是控制字符如换行.回车.删 除等,32~126是打印字符,可以通 ...
-
出现 java.lang.OutOfMemoryError: PermGen space 错误的原因及解决方法
一.原因及解决方法[1] 1.原因:堆内存的永久保存去区内存分配不足(缺省默认为64M),导致内存溢出错误. 2.解决方法:重新分配内存大小,-Xms1024M -Xmx2048M -XX:PermS ...
-
java.sql.SQLException: Field &#39;login_date&#39; doesn&#39;t have a default value解决方法
在做web项目的insert插入操作的时候, 由于对于一个字段没有插入数据, xml文件写法如下: <insert id="savePremissUser" > ins ...
随机推荐
-
WPF 变量转换的实现
有时候,我们传入的是一个值,但是真正显示的需要是另一个值,这时候就需要转换.比如我们传入一个枚举值,而不同的枚举值对于的图片是不一样的. 这时候就需要一个转换规则.WPF里面给我们提供了一个接口IVa ...
-
NetMQ(二): 请求响应模式 Request-Reply
ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...
- 运行Myeclipse发生这事这是怎么回事,大神们
-
在多台PC上进行ROS通讯-学习笔记
首先,致谢易科(ExBot)和ROSWiki中文社区. 重要参考文献: Running ROS across multiple machines http://wiki.ros.org/ROS/Tut ...
-
排序之选择排序(SelectSort)
package com.sort; /* * 选择排序 * 把第一位与其他数进行比较,这样每轮比较都会出现一个最大值或最小值 * 根据需要让升序或降序排列 */ public class Select ...
-
Python打包—Pyinstaller
2018-09-27 21:12:05 一 前言 在windows平台学习python的过程中,你肯定会遇到需要把.py脚本打包成.exe的情形,如此,至少有两方面的好处:第一,你的代码保密性更好 ...
-
8.2.优化SQL语句
8.2.优化SQL语句 数据库应用程序核心操作逻辑都是通过执行SQL语句来执行,不管是直接通过解释器还是通过后台API提交. 调优手册里面的这一节内容帮助各种各样MySQL程序加快速度.手册包括SQL ...
-
雷达波Shader
OSG版本: vert #version varying out vec3 v; void main() { gl_FrontColor = gl_Color; gl_Position = ftran ...
-
Azure Sql Database为某个数据库创建单独的访问账户
由于SQL Management Studio对Azure SQL Database支持不完美,不能使用图形界面,因此配置数据库就会有不同的麻烦,下面是本人配置访问账户的一些经验: 1.以管理员登陆之 ...
-
centos 7 bbr 安装
1. 准备 升级内核需要4.9 以及以上 2. yum 内核升级 a. 添加 ELRepo 源 GPG key rpm --import https://www.elrepo.or ...