说明:由于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文件解决乱码问题的更多相关文章

  1. Java读取txt文件

    package com.loongtao.general.crawler.slave.utils; import java.io.BufferedReader; import java.io.File ...

  2. java 读取TXT文件的方法

    java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...

  3. java读取TXT文件的方法

    java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...

  4. java读取txt文件内容

    package read; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; public ...

  5. java读取txt文件的2中方法---并将内容(每一行以固定的字符分割切成2段)存到map中去

    #java读取txt文件的第一种方法 /** * 方法:readTxt * 功能:读取txt文件并把txt文件的内容---每一行作为一个字符串加入到List中去 * 参数:txt文件的地址 * 返回: ...

  6. Java读取txt文件信息并操作。

    一.java读取txt文件内容 import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.Fi ...

  7. Java读取txt文件、excel文件的方法

    Java读取txt文件.excel文件的方法 1.读取txt文件 public static String getFileContent(String filePath,String charset) ...

  8. 关于读取txt文件中文乱码问题

    在处理文件的过程中,读取txt文件出现中文乱码.这种情况是由于编码字符不一致导致. public static string ReadFile(string path, string fileName ...

  9. JAVA 读取txt文件内容

    原文地址https://www.cnblogs.com/xing901022/p/3933417.html 通常,我们可以直接通过文件流来读取txt文件的内容,但有时可能会出现乱码!此时只要设置一下文 ...

  10. Java 读取TXT文件的多种方式

    1).按行读取TXT文件package zc;import java.io.BufferedReader;import java.io.File;import java.io.FileNotFound ...

随机推荐

  1. TypeScript 引用资源文件后提示找不到的异常处理

    在tsx中引用图片,在文件文本编辑器中提示错误引用: typescript无法识别非代码文件(js是可以的).如果需要在ts中识别此文件资源,可以先声明文件类型. 新建一个ts文件,比如global. ...

  2. 一文讲透 RocketMQ 消费者是如何负载均衡的

    RocketMQ 支持两种消息模式:集群消费( Clustering )和广播消费( Broadcasting ). 集群消费:同一 Topic 下的一条消息只会被同一消费组中的一个消费者消费.也就是 ...

  3. C++ Primer 5th 阅读笔记:入门指南

    学习方法 The way to learn a new programming language is to write programs. 学习一门新编程语言的方式是编写程序. 函数(Functio ...

  4. pytest常用断言

    如上官网所说,pytest使用python中的assert来比较实际值与预期值,实现断言功能 1 常用的断言方式 assert xxx assert a == b assert a!=b assert ...

  5. VUE旅程(2)

    继续我的vue踩坑之旅... 电商网站都会有搜索栏,输入内容后在搜索结果页面要带入搜索的关键字,需求就从这里来.代码如下: <v-search :keyword="this.$rout ...

  6. 2021-01-11:linux中,如何看内存的使用情况呢?

    福哥答案2021-01-11: 1.free:查看内存占用情况,会直接返回,常用参数 -M.-G 是以MB或GB为单位返回结果.2.sar:定时检测系统资源占用情况,-r 参数是内存资源,一般用法 s ...

  7. 2022-02-02:最接近的二叉搜索树值 II。 给定一个不为空的二叉搜索树和一个目标值 target,请在该二叉搜索树中找到最接近目标值 target 的 k 个值。 注意: 给定的目标值 ta

    2022-02-02:最接近的二叉搜索树值 II. 给定一个不为空的二叉搜索树和一个目标值 target,请在该二叉搜索树中找到最接近目标值 target 的 k 个值. 注意: 给定的目标值 tar ...

  8. 开发者一定要知道的 API 管理五大趋势

    API First 大势所趋,APIaaS(API 作为服务)也将受到越来越多企业和组织的选择,研发团队对 API 研发管理工具的要求也水涨船高. API 在今天的数字化世界中扮演着至关重要的角色,随 ...

  9. Java程序设计复习提纲(上:入门语法)

    目录 上: 基本语法与编译运行 数据类型和关键字 常用语法 数组与字符串 异常处理 中: 面向对象和类 下: 图形界面 基本语法与编译运行 java没有指针没有全局变量 Java源代码文件的后缀名是& ...

  10. vue3+vite2+element-plus+ts搭建一个项目

    花了几天用 vue3+ vite2+ element-plus+ ts 搭了个 极简版骨架型数据管理系统,使用静态数据模拟动态路由,路由拦截,登录页面鉴权等,使用了iconify字体图标,整合了ces ...