说明:由于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. 笔记:C++学习之旅 ---string 类、vector和迭代器

    string 类 #include <iostream> #include <string> using namespace std; int main() {         ...

  2. vue本地开发配置及项目部署

    一,  二,本地模拟配置代理,请求qq音乐的接口数据  三,axios请求头封装               参考http://www.axios-js.com/zh-cn/docs/#%E4%BB% ...

  3. node 请求接口,返回大小限制

    请求Node端中转接口时,遇到以下异常: Request_fileSize_limit Request_fields_limit Request_fieldSize_limit 遇到以上异常时,调试信 ...

  4. [Opencv-C++] 3. opencv数据类型

    文章目录 Point类 cv::Scalar类 size类 cv::Rect类 cv::RotatedRect类 固定矩阵类 固定向量类 复数类 工具函数 模板结构 Point类 在大多数程序中,Po ...

  5. 联想win8改win7

    知识点分析:目前联想出厂预装Windows 8的台式和一体机使用都是UEFI+GPT硬盘的组合,并且开启了安全启动,但是目前除Window 8以外的其他Windows系统均不支持这种模式,因此如果需要 ...

  6. 关于Mybatis

    一:Mybatis的优缺点 优点: 1.与JDBC相比,减少了百分之五十的代码量. 2.Mybatis是最简单的持久层框架,简单易学. 3.Mybatis灵活,不会对应用程序和现数据库设计强加任何影响 ...

  7. SVN添加新的用户

    1.首先确定svn的文件夹的位置 find / -name svn 2.通过find找到svn地址之后,cd进入 /var/svn/ 下 cd /var/svn/ 3.修改/var/svn/下面的au ...

  8. 2022-12-10:给你一个由小写字母组成的字符串 s ,和一个整数 k 如果满足下述条件,则可以将字符串 t 视作是 理想字符串 : t 是字符串 s 的一个子序列。 t 中每两个 相邻 字母在字

    2022-12-10:给你一个由小写字母组成的字符串 s ,和一个整数 k 如果满足下述条件,则可以将字符串 t 视作是 理想字符串 : t 是字符串 s 的一个子序列. t 中每两个 相邻 字母在字 ...

  9. 2020-08-19:TCP是通过什么机制保障可靠性的?

    福哥答案2020-08-19: 福哥口诀法:校(jiao)序确重拥流连(tcp可靠性保障机制:校验.序号.确认.重传.拥塞.流量.连接)校验:数据是否正确.序号:对数据编号seq.确认:ACK.重传: ...

  10. 2021-10-04:解码方法 II。‘A‘ -> 1,‘B‘ -> 2,...‘Z‘ -> 26。*是1-9,不包含0。给你一个字符串 s ,由数字和 ‘*‘ 字符组成,返回 解码 该字符串的方法

    2021-10-04:解码方法 II.'A' -> 1,'B' -> 2,-'Z' -> 26.是1-9,不包含0.给你一个字符串 s ,由数字和 '' 字符组成,返回 解码 该字符 ...