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 ...
随机推荐
- Python 遍历整个列表
操作列表 遍历整个列表,无论列表有多长,循环让列表中的每一个元素都采取一个或一系列相同的措施,从而高效地处理任何长度的列表,包含数以千至数百万个元素的列表. 遍历整个列表 通过for循环解决遍历 从列 ...
- Swagger之学习使用
前言 这个是为了介绍一下Swagger的使用,最近也在使用Swagger,就在下面这篇文章介绍下,我特地改了上次分享的外卖项目,添加了Swagger注解- 添加依赖 Maven项目添加依赖 <d ...
- C# 实现窗体启动时隐藏
在某些时候需要实现一个界面的后台程序,程序自动运行,但起初不显示窗体,在满足触发条件时显示,此时需要在运行程序时先自动隐藏窗体. 修改窗体对应的Program.cs: using System; us ...
- Vue3项目的打包运行
一.项目打包(vite创建的项目) 执行以下这条命令对项目进行打包 npm run build 生成dist文件夹,进入dist文件夹下的index.html文件,然后右键选择Open with Li ...
- Java商城网站系统设计与实现(带源码)
基于Java的商城网站系统设计与实现 功能介绍 平台采用B/S结构,后端采用主流的Springboot框架进行开发,前端采用主流的Vue.js进行开发. 整个平台包括前台和后台两个部分. 前台功能包括 ...
- 神经网络初步(Neural Network)——思想 具体实例以及代码实现
在前面我们详细的讨论过softmax损失函数以及SVM损失函数,以及应用了支持向量机进行图片分类的任务,不妨先复习一下支持向量机相关的思想内核:支持向量机想要寻求一组映射关系f(x)=wx+b,先将每 ...
- cve_2020_6507分析
poc $ cat poc.js array = Array(0x40000).fill(1.1); args = Array(0x100 - 1).fill(array); args.push(Ar ...
- ffuf的使用
ffuf:模糊测试 使用 ffuf 进行枚举.模糊测试和目录暴力破解 安装 https://github.com/ffuf/ffuf 建议:https://github.com/danielmiess ...
- CANoe _ Panel面板的创建过程
在Canoe中创建Panel面板,用于显示和操作CAN网络的数据和信号,遵循以下步骤: 1.打开Canoe 启动Canoe软件. 2.打开项目 在Canoe的菜单栏中,选择"File&quo ...
- @Retention元注解的使用
@Retention注解标记其他的注解用于指明标记的注解保留策略:先看Java SE 8中@Target是如何声明的: package java.lang.annotation; public enu ...