java读取txt文件解决乱码问题
说明:由于txt文件有bom和不同的编码方式,导致导入数据时产生乱码,以下代码完美解决乱码问题。
参考他人代码,结合自己的业务加工完成,费了大半天功夫完成,希望对大家有点用处。
废话不多说,直接上代码:
/**
* 从txt文件流读取数据
*
* @param txtStream
* @return
* @throws IOException
*/
public static List<String> readFromTxt(InputStream txtStream) throws IOException {
List<String> paragraphList = new ArrayList<>();
LabelValuePair<InputStream, Charset> result = getStreamCharset(txtStream);
Charset cs = result.getValue();
BOMInputStream bomInputStream = new BOMInputStream(result.getLabel());
boolean hasBom = bomInputStream.hasBOM();
InputStreamReader sr = hasBom ?
new InputStreamReader(bomInputStream, Charset.forName(bomInputStream.getBOMCharsetName())) :
new InputStreamReader(bomInputStream, cs);
BufferedReader br = new BufferedReader(sr);
String line = null;
Integer lineIndex = 0;
while ((line = br.readLine()) != null) {
if (!hasBom && lineIndex == 0) {
lineIndex++;
if (StringUtils.isNotEmpty(line)) {
byte[] bts = line.getBytes(cs);
if ((bts[0] == -1 && bts[1] == -2) || bts[0] == -2 && bts[1] == -1) {
byte[] newBts = new byte[bts.length - 2];
for (int i = 2; i < bts.length; i++) {
newBts[i - 2] = bts[i];
}
line = new String(newBts, cs);
}
}
}
if (StringUtils.isNotEmpty(line) && StringUtils.isNotEmpty(line.trim())) {
paragraphList.add(line);
log.info("读取数据:{},长度:{},value:{}", line, line.trim().length(), line.getBytes(cs));
}
}
br.close();
sr.close();
return paragraphList;
}
/**
* 判断获取字节流 编码格式,主要用于txt文件内容读取
* 再次读取流,使用返回结果中的流
*
* @param stream
* @return
*/
public static LabelValuePair<InputStream, Charset> getStreamCharset(InputStream stream) throws IOException {
LabelValuePair<InputStream, byte[]> result = readSteam(stream, true);
byte[] buffer = result.getValue();
if (buffer.length < 2)
return new LabelValuePair<>(result.getLabel(), CharsetKit.CHARSET_GBK);
String encode = getFileCharSet(new BufferedInputStream(new ByteArrayInputStream(result.getValue())));// getBytesCharset(buffer);
return new LabelValuePair<>(result.getLabel(), CharsetKit.charset(encode));
}
/**
* 判断txt编码格式方法
*
* @param bis
* @return
*/
public static String getFileCharSet(BufferedInputStream bis) {
String charset = "GBK";
byte[] first3Bytes = new byte[3];
try {
boolean checked = false;
bis.mark(0);
int read = bis.read(first3Bytes, 0, 3);
if (read == -1) {
return charset; //文件编码为 ANSI
} else if (first3Bytes[0] == (byte) 0xFF
&& first3Bytes[1] == (byte) 0xFE) {
charset = "UTF-16LE"; //文件编码为 Unicode
checked = true;
} else if (first3Bytes[0] == (byte) 0xFE
&& first3Bytes[1] == (byte) 0xFF) {
charset = "UTF-16BE"; //文件编码为 Unicode big endian
checked = true;
} else if (first3Bytes[0] == (byte) 0xEF
&& first3Bytes[1] == (byte) 0xBB
&& first3Bytes[2] == (byte) 0xBF) {
charset = "UTF-8"; //文件编码为 UTF-8
checked = true;
}
bis.reset();
if (!checked) {
int loc = 0;
while ((read = bis.read()) != -1) {
loc++;
if (read >= 0xF0)
break;
if (0x80 <= read && read <= 0xBF) // 单独出现BF以下的,也算是GBK
break;
if (0xC0 <= read && read <= 0xDF) {
read = bis.read();
if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF)
// (0x80
// - 0xBF),也可能在GB编码内
continue;
else
break;
} else if (0xE0 <= read && read <= 0xEF) {// 也有可能出错,但是几率较小
read = bis.read();
if (0x80 <= read && read <= 0xBF) {
read = bis.read();
if (0x80 <= read && read <= 0xBF) {
charset = "UTF-8";
break;
} else
break;
} else
break;
}
}
}
bis.close();
} catch (Exception e) {
log.error("获取文件编码方式异常", e);
}
return charset;
}
/**
* 读取流
*
* @param inputStream 输入流
* @param isRepeat 是否重复读取
* @return
*/
public static LabelValuePair<InputStream, byte[]> readSteam(InputStream inputStream, boolean isRepeat) throws IOException {
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
inputStream.mark(0);
while ((len = inputStream.read(buffer)) != -1) {
outSteam.write(buffer);
}
byte[] fs = outSteam.toByteArray();
outSteam.close();
inputStream.close();
InputStream newSteam = null;
if (isRepeat) {
newSteam = new ByteArrayInputStream(fs);
}
return new LabelValuePair<>(newSteam, fs);
}
java读取txt文件解决乱码问题的更多相关文章
- Java读取txt文件
package com.loongtao.general.crawler.slave.utils; import java.io.BufferedReader; import java.io.File ...
- java 读取TXT文件的方法
java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...
- java读取TXT文件的方法
java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...
- java读取txt文件内容
package read; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; public ...
- java读取txt文件的2中方法---并将内容(每一行以固定的字符分割切成2段)存到map中去
#java读取txt文件的第一种方法 /** * 方法:readTxt * 功能:读取txt文件并把txt文件的内容---每一行作为一个字符串加入到List中去 * 参数:txt文件的地址 * 返回: ...
- Java读取txt文件信息并操作。
一.java读取txt文件内容 import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.Fi ...
- Java读取txt文件、excel文件的方法
Java读取txt文件.excel文件的方法 1.读取txt文件 public static String getFileContent(String filePath,String charset) ...
- 关于读取txt文件中文乱码问题
在处理文件的过程中,读取txt文件出现中文乱码.这种情况是由于编码字符不一致导致. public static string ReadFile(string path, string fileName ...
- JAVA 读取txt文件内容
原文地址https://www.cnblogs.com/xing901022/p/3933417.html 通常,我们可以直接通过文件流来读取txt文件的内容,但有时可能会出现乱码!此时只要设置一下文 ...
- Java 读取TXT文件的多种方式
1).按行读取TXT文件package zc;import java.io.BufferedReader;import java.io.File;import java.io.FileNotFound ...
随机推荐
- [人脸活体检测] 论文:Face De-Spoofing: Anti-Spoofing via Noise Modeling
Face De-Spoofing: Anti-Spoofing via Noise Modeling 论文简介 将非活体人脸图看成是加了噪声后失真的x,用残差的思路检测该噪声从而完成分类. 文章引用量 ...
- Locust 任务类介绍
前言: 任务:简单的理解就是,你想要你脚本的虚拟用户去做哪些事,比如请求某一个接口,或者执行某一个事件 用户:可以理解为,执这个任务的实例主体,或者在locust 中,也可以认为是一群蝗虫 一.Tas ...
- Swagger之学习使用
前言 这个是为了介绍一下Swagger的使用,最近也在使用Swagger,就在下面这篇文章介绍下,我特地改了上次分享的外卖项目,添加了Swagger注解- 添加依赖 Maven项目添加依赖 <d ...
- RabbitMQ系列-概念及安装
1. 消息队列 消息队列是指利用队列这种数据结构进行消息发送.缓存.接收,使得进程间能相互通信,是点对点的通信 而消息代理是对消息队列的扩展,支持对消息的路由,是发布-订阅模式的通信,消息的发送者并不 ...
- S32DS---make: *** No rule to make target 'clean'. Stop和make: *** No rule to make target 'all'. Stop的一个解决方法
问题: 最近在用S32DS调试代码的时候,遇到一个稀奇古怪的问题: and 折腾了半天,发现从这个页面导入工程编译就不会出现这个问题???? file-->import projects fro ...
- HTTP请求:requests模块基础使用必知必会
1 背景 http请求是常见的一种网页协议,我们看到的各种网页,其实都是发送了http请求得到了服务器的响应,从而将数据库中复杂的数据以简单.直观的方式呈现出来,方便大众阅读.使用.而如何发送http ...
- pcie reset系列之 内核框架
FLR是pci reset的一种. 关于FLR的寄存器操作比较简单, 相关的寄存器有: 配置空间里device cap里的FLR capability bit, 这个表示设备是否支持FLR. 配置空间 ...
- OAuth2.0andmultifactorauthentication:Howtocreateasecure
目录 1. 引言 2. 技术原理及概念 2.1. 基本概念解释 2.2. 技术原理介绍 2.3. 相关技术比较 3. 实现步骤与流程 3.1. 准备工作:环境配置与依赖安装 随着数字化时代的到来,人们 ...
- 在命令行按下tab键之后, 发生了生么?
1. 引言 2. complete命令 3. 自定义补全列表 4. 动态补全列表 5. compgen命令 6. 别名的自动补全 7. 补全规则永久生效 8. 自动加载 9. 参考 1. 引言 当我们 ...
- ASP.NET Core 6框架揭秘实例演示[40]:基于角色的授权
ASP.NET应用并没有对如何定义授权策略做硬性规定,所以我们完全根据用户具有的任意特性(如性别.年龄.学历.所在地区.宗教信仰.政治面貌等)来判断其是否具有获取目标资源或者执行目标操作的权限,但是针 ...