使用IO流导致数据乱码的同学也可以借鉴一下

老规矩先上代码:

/*** @author FastKing* @version 1.0* @date 2018/11/29 9:11**/
public class TikaTest {public static void main(String[] args) {try {FileInputStream is = new FileInputStream(new File("E:\\账号密码.txt"));BodyContentHandler bodyContentHandler = new BodyContentHandler();//获取文件编码格式Charset charset = new AutoDetectReader(is).getCharset();String encodeName = charset.name();System.out.println(encodeName);//获取txt文档内容,乱码处理is.reset();new TXTParser().parse(is, bodyContentHandler, new Metadata(), new ParseContext());System.out.println(charset.contains(Charset.forName("UTF-8")) ? bodyContentHandler.toString() : new String(bodyContentHandler.toString().getBytes(encodeName)));} catch (IOException | TikaException | SAXException e) {e.printStackTrace();}}
}

如果单纯的只是想提取文本内容,很多博主都写了对应的入门demo,这里我主要说一下乱码的问题,以txt提取内容为例:

看了一下源码:

public void parse(InputStream stream, ContentHandler handler, Metadata metadata, ParseContext context) throws IOException, SAXException, TikaException {AutoDetectReader reader = new AutoDetectReader(new CloseShieldInputStream(stream), metadata, this.getEncodingDetector(context));Throwable var6 = null;try {String incomingMime = metadata.get("Content-Type");MediaType mediaType = MediaType.TEXT_PLAIN;if (incomingMime != null) {MediaType tmpMediaType = MediaType.parse(incomingMime);if (tmpMediaType != null) {mediaType = tmpMediaType;}}Charset charset = reader.getCharset();MediaType type = new MediaType(mediaType, charset);metadata.set("Content-Type", type.toString());metadata.set("Content-Encoding", charset.name());XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);xhtml.startDocument();xhtml.startElement("p");char[] buffer = new char[4096];for(int n = reader.read(buffer); n != -1; n = reader.read(buffer)) {xhtml.characters(buffer, 0, n);}xhtml.endElement("p");xhtml.endDocument();} catch (Throwable var21) {var6 = var21;throw var21;} finally {if (reader != null) {if (var6 != null) {try {reader.close();} catch (Throwable var20) {var6.addSuppressed(var20);}} else {reader.close();}}}}

在tika执行parse的时候,会先使用AutoDetectReader中的getEncodingDetector,猜测这和java中的Reader一样,都是以系统默认编码来读取输入流。

那发生乱码的原因也就很明显了,当你源文件的编码格式不能被你系统编码格式正确转码的时候,就会产生乱码。

举个例子,比如说你源文件的编码格式为ISO-8859-1,而系统编码格式为UTF-8,读取出来的数据就会乱码;而如果你源文件的编码格式为UTF-16,系统编码格式为UTF-8,读取出来的数据就不会乱码。再形象一点来说,ISO-8859-1和UTF-8不是一家子,而UTF-16和UTF-8是一家子。

既然清楚了发生乱码的原因,再说一下解题思路,既然在parse的时候无法指定读取文件流的编码格式,那么我们就要在parse之后对产生乱码的字符串进行转码。

首先判断是否会产生乱码,在java.nio中,Charset有个contains的方法,看了一下官方文档:

意思大概就是,如果一个字符被两种编码格式编码后的字符相同,则返回true,说明这两种编码格式存在包含关系

系统编码格式是本身就知道的(大部分开发者都选用UTF-8),那原文件的编码格式如何获取呢,tika中提供了这样的方法:

Charset charset = new AutoDetectReader(is).getCharset();

在这里有一个坑需要注意一下,tika源码中这样写道:

private AutoDetectReader(InputStream stream, Charset charset) throws IOException {super(new InputStreamReader(stream, charset));this.charset = charset;this.mark(1);if (this.read() != 65279) {this.reset();}}

说明tika在判断源文件编码的时候会先使用输入流读一下,而输入流在执行读操作的时候,会把流的头标记移动到读操作结束的位置,这样就导致数据丢失,我们得在tika执行parse之前reset一下,让输入流的头标记回到最开始的位置。

Tika提取txt文档内容,以及乱码处理相关推荐

  1. C#提取TXT文档指定内容

    早上有分享一篇<VB.NET提取TXT文档指定内容> http://www.cnblogs.com/insus/p/3267347.html 那是原网友的需求用VB.NET写的. 刚才有只 ...

  2. Python读取.txt文档内容/读取text文件内容

    Python读取.txt文档内容/读取text文件内容; 读取txt后缀文件的内容的两种方式,简约易懂,复制粘贴即可食用,节约你宝贵的时间 文档全部数据一次性读取 # -*- coding: UTF- ...

  3. 提取txt文档中以冒号分隔符区分的信息到excel(前提是使用正则表达式把每一行修改为只有一个冒号)

    文本样式:(使用正则表达式替换为每一行最多有一个冒号) 1. 机构名称:AAAAA 许可证号:BBBBB 住所:CCCCC 邮编:DDDDD 法定代表人:EEEEE 电话:11111111 业务范围: ...

  4. 读取DOC、DOCX、 XLS 、XLSX 、PDF 、PPTX 、TXT文档内容

    读取DOC.DOCX. XLS .XLSX .PDF .PPTX .TXT文档内容 POM 依赖 <!-- https://mvnrepository.com/artifact/org.apac ...

  5. 如何批量提取 PDF 文档内容,将 PDF 格式文档转为 Txt 文本格式

    概要:PDF 文档常常用来阅读.预览或者存档一些资料,PDF 支持的内容也是比较丰富的.可以支持图片.文本等多种类型的元素.那有时候我们就需要将一些纯文本的 PDF 文档中的文字提取出来,转为一个 T ...

  6. Scrapy笔记(2)——使用正则表达式提取jQuery文档内容

    任务:提取如下网页中Data中内容: jQuery1123006065544693397551_1623470103055({"Message":"",&quo ...

  7. tika 解析html table,TIKA提取HTML文档

    全屏 下面给出的是该程序用于从HTML文档提取内容和元数据.import java.io.File; import java.io.FileInputStream; import java.io.IO ...

  8. 批量删除txt文档内容命令_Linux@实用操作命令

    帮助 当我们对某个指令不熟悉时,我们可以使用 Linux 提供的帮助指令来了解这个指令的使用方法. man 命令:man [命令或配置文件] 功能描述:获得帮助信息 案例:查看 ls 命令的帮助信息 ...

  9. matlab修改txt文档内容

    方法一:使用fscanf函数,但会出现问题:读入的数据类型必须相同,否则不能读入. 方法二:按行读取按行修改,可以完成任务要求,缺点是相对费时.以下介绍具体步骤. (1)以读的形式打开文本:fopen ...

最新文章

  1. lemp-------3多站点访问,,访问控制,,虚拟目录
  2. 控制~Matlab非线性模型分析
  3. accept系统调用内核实现
  4. python3入门基础语法总结_Python基础语法总结
  5. spark.mllib源码阅读:GradientBoostedTrees
  6. oracle 取消exp权限,oracle 复制账号权限oracle11gexp导出问题:部分表导不出来
  7. curl 伪装来路(referer)
  8. python机器学习2021年6月19日09:35:06
  9. network of emergency contacts---BFS
  10. 11月20日站立会议
  11. ActionScript 中的字符串替换函数
  12. 在Android studio中出现 ‘opencv2/opencv.hpp‘ file not found
  13. Ubuntu设置系统时间与网络时间同步
  14. Python爬虫实战:1000图库大全【别轻易点进来】
  15. 抖音壁纸表情包小程序源码,可对接流量主
  16. html5怎么做京东表格,HTML+CSS+PS 编写京东商城首页
  17. 【Hexo】nexT主题使用攻略基础——添加分类、标签及关于
  18. 常见设计模式快速记忆
  19. 要不要试试 FBI 出品的健身APP,绝对不收集信息
  20. 2113: 小飞的游戏

热门文章

  1. C语言判断三角形类型并给出周长
  2. 数学建模十大算法02—插值与拟合(拉格朗日插值、三次样条插值、线性最小二乘法……)
  3. lucene php,用PHP调用Lucene包来实现全文检索_php
  4. android餐厅菜单功能,基于Android平台的菜谱实现
  5. Android 调用第三方地图进行导航
  6. App 创业者的福音,应用质量问题将完美解决
  7. 生产追溯系统-Wifi+传感器,实现计数器以及监控机器是否停止
  8. 什么是智慧路灯网关 一体式智慧灯杆方案
  9. iis服务器证书,Internet Information Services (IIS) 服务器证书安装说明
  10. 『迷你教程』泰勒级数(Taylor series)的通俗看法