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 ...
随机推荐
- Locust 任务类介绍
前言: 任务:简单的理解就是,你想要你脚本的虚拟用户去做哪些事,比如请求某一个接口,或者执行某一个事件 用户:可以理解为,执这个任务的实例主体,或者在locust 中,也可以认为是一群蝗虫 一.Tas ...
- 2021-11-05:摆动排序 II。给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序。你可以假设所有输入数组都可以
2021-11-05:摆动排序 II.给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]- 的顺序.你可以假设所有 ...
- 2021-10-14:被围绕的区域。给你一个 m x n 的矩阵 board ,由若干字符 ‘X‘ 和 ‘O‘ ,找到所有被 ‘X‘ 围绕的区域,并将这些区域里所有的 ‘O‘ 用 ‘X‘ 填充。力扣1
2021-10-14:被围绕的区域.给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充.力扣1 ...
- Solon v2.2.17 发布,Java 新的生态型应用开发框架
相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) qps 高 2- 3 倍. (更高) 运行时内存节省 1/3 ~ 1/2. (更少) 打包 ...
- L1-025 正整数A+B (15 分)
1.题目描述: 题的目标很简单,就是求两个正整数A和B的和,其中A和B都在区间[1,1000].稍微有点麻烦的是,输入并不保证是两个正整数. 输入格式: 输入在一行给出A和B,其间以空格分开.问题是A ...
- Docker-Compose快速搭建LNMP
Docker-Compose 1.安装Docker sudo apt -y install docker.io docker version 查看版本号 docker help 查看帮助文档 2.更换 ...
- 使用 conda 和 Jupyter 创建你的自定义 R 包,转换笔记为幻灯片
创建你的自定义 R 包 出于用户使用方便考虑,Anaconda 已经在 "R Essentials" 中打包了一些最常用的数据科学 R 包.使用 conda metapackage ...
- 三分钟免费将 Claude API 接入个人服务
首先我们介绍一下今天的主角 Claude Claude 是最近新开放的一款 AI 聊天机器人,是世界上最大的语言模型之一,比之前的一些模型如 GPT-3 要强大得多,因此 Claude 被认为是 Ch ...
- 强国杯南部西部赛区分区晋级赛WP
Misc 空白文件 解压的文件,通过kali strings 查看到base64加密,把%7B换成'{',%7D换成'}' 迷惑的时间 导出3.jpg原始数据信息 去掉没用的头部信息,得到3.jpg图 ...
- 关于进程、线程、协程的概念以及Java中的应用
进程.线程.协程 本文将从"操作系统"."Java应用"上两个角度来探究这三者的区别. 一.进程 在我本人的疑惑中,我有以下3个问题. 1.1为什么要引入进程? ...