用Java将QQ、企业QQ导出的消息(mht格式)(支持大文件)解析为html格式,包含解析图片内容
代码地址见本文最后。
因为特殊原因,更换了通讯工具,需要将原聊天消息进行备份,并能进行浏览或者查询。
发现QQ消息可以导出mht格式的消息,这种文件格式内部其实就是讲html、css、图片(图片是经过base64转换)按照一定规律全部写入到mht文件中的,只要按照规律解析即可。
在解析的过程中,如果是文件体积比较大,就需要考虑进行分页,否则生成的html文件很大,我遇到解析后最大的单html文件达到了500M(导出全部消息),浏览起来很不方便,因此增加了分页功能。
首先上效果:
1.将程序放到mht文件所在文件夹。
程序会自动查询当前文件夹的mht文件,并进行转换,最后将文件保存到mht同名的文件夹中。
2.双击运行run.bat文件,可选分页。
注意:在mht文件小于100M的情况下,即使选择了分页,程序不会也不会进行分页。
3.预览效果
部分代码解析:
1.生成单文件html
/*** 创建单文件html* @param inputFile* @param outputFilePath*/public static void readAndCreateFile(String inputFile, String outputFilePath) {String htmlFileName = parseHtmlFileName(inputFile);File file = new File(inputFile);BufferedInputStream fis = null;BufferedReader reader = null;try {fis = new BufferedInputStream(new FileInputStream(file));reader = new BufferedReader(new InputStreamReader(fis,"utf-8"),5*1024*1024);boolean isCreatedHtml = false, isHtmlContent = false;String line = "";StringBuilder sb = null;//String [] resType = null;String resName = null;//boolean isGetResType = false;boolean isGetResName = false;StringBuilder resSb = new StringBuilder();while((line = reader.readLine()) != null){if(!isCreatedHtml) {if (isHtmlStartTag(line)) {isHtmlContent = true;sb = new StringBuilder(line).append("\n");}else{if(isHtmlContent) {if (isHtmlEndTag(line)) {sb.append(line).append("\n");createHtmlFile(outputFilePath, htmlFileName, sb.toString(), 0, true);sb.delete(0, sb.length());isCreatedHtml = true;} else {sb.append(line).append("\n");}}}}/*** 开始解析资源文件*/if(isCreatedHtml) {/*if(!isGetResType) {resType = parseResourceType(line);if (resType != null) {isGetResType = true;continue;}}*/if(!isGetResName) {resName = parseResourceName(line);if (resName != null) {isGetResName = true;resSb.delete(0, resSb.length());continue;}}if(isGetResName) {if(line.length() > 0) {if(line.contains("------=_NextPart_")) {//isGetResType = false;isGetResName = false;generateImage(resSb.toString(), (outputFilePath + File.separator + htmlFileName), resName);}else{resSb.append(line).append("\n");}}}}}} catch (FileNotFoundException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if(reader != null) {reader.close();}if(fis != null) {fis.close();}} catch (IOException e) {e.printStackTrace();}}}
2.生成分页html
/*** 创建分页html* @param inputFile* @param outputFilePath*/public static void readAndCreateMultFile(String inputFile, String outputFilePath) {String htmlFileName = parseHtmlFileName(inputFile);File file = new File(inputFile);BufferedInputStream fis = null;BufferedReader reader = null;try {fis = new BufferedInputStream(new FileInputStream(file));reader = new BufferedReader(new InputStreamReader(fis,"utf-8"),5*1024*1024);boolean isCreatedHtml = false, isTableContent = false;String line = "";StringBuilder sb = null;int trLine = 1;int htmlNo = 1;//String [] resType = null;String resName = null;//boolean isGetResType = false;boolean isGetResName = false;StringBuilder resSb = new StringBuilder();while((line = reader.readLine()) != null){if(!isCreatedHtml) {Matcher startMatcher = tableStartPattern.matcher(line);if (startMatcher.find()) {isTableContent = true;/*** 将table后面的内容拼接起来*/sb = new StringBuilder(line.substring(startMatcher.end())).append("\n");}else{if(isTableContent) {trLine++;Matcher endMacher = tableEndPattern.matcher(line);if (endMacher.find()) {sb.append(line.substring(0, endMacher.start()));createHtmlFile(outputFilePath, htmlFileName, sb.toString(), htmlNo, true);isCreatedHtml = true;} else {sb.append(line).append("\n");if(trLine % 1000 == 0) {createHtmlFile(outputFilePath, htmlFileName, sb.toString(), htmlNo, false);htmlNo ++;sb.delete(0, sb.length());}}}}}/*** 开始解析资源文件*/if(isCreatedHtml) {/*if(!isGetResType) {resType = parseResourceType(line);if (resType != null) {isGetResType = true;continue;}}*/if(!isGetResName) {resName = parseResourceName(line);if (resName != null) {isGetResName = true;resSb.delete(0, resSb.length());continue;}}if(isGetResName) {if(line.length() > 0) {if(line.contains("------=_NextPart_")) {//isGetResType = false;isGetResName = false;generateImage(resSb.toString(), (outputFilePath + File.separator + htmlFileName), resName);}else{resSb.append(line).append("\n");}}}}}} catch (FileNotFoundException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if(reader != null) {reader.close();}if(fis != null) {fis.close();}} catch (IOException e) {e.printStackTrace();}}}
注意:
1.考虑到性能问题,分页生成的时候,只做了上一页、下一页,因为个人已经觉得这个够用了,并没有开发页码的功能,读者可对这个进行扩展,思路大概是:将mht中的html部分读取到,主要是table中的tr部分,然后将这些逐条读取到并放入list,然后根据list进行分页。
2.读者在转换之后,还是请保留您的原始mht文件,虽然功能经过测试,也对数据进行了一定量的验证,但是不保证在转换的过程中可能因bug或未知因素导致数据丢失,因此,请保留原始mht文件,请保留原始mht文件,请保留原始mht文件!
3.花了一点时间开发的,并未对代码进行优化,可能有些地方有部分重复代码,读者请自行优化。
4.测试过6G和10G左右的文件,更大的文件暂时未测试。
后续:
后续如果有空闲时间,可能会做一定的改进,使用Lucene相关技术,对生成的html进行索引并支持搜索,方便搜索消息。
代码地址:
https://github.com/itriders/mht2html
用Java将QQ、企业QQ导出的消息(mht格式)(支持大文件)解析为html格式,包含解析图片内容相关推荐
- Java中利用企业QQ邮箱发送邮件
package test; import java.util.Date; import java.util.Properties; import javax.mail.internet.Interne ...
- java nio 按行读取_JAVA之NIO按行读写大文件,完美解决中文乱码问题
packagecom.chillax.imp; importjava.io.File; importjava.io.IOException; importjava.io.RandomAccessFil ...
- java录制pcm文件_AudioRecord录制PCM格式的语音示例
AudioRecord可以将手机或麦克风的声音录制成pcm格式的语音文件,本案例将再service中实现pcm声音的录制,并提供将pcm格式语音转化为mp3格式的方法,先来看看AudioRecord如 ...
- java EE 5配置邮件发送 qq企业邮箱
为什么80%的码农都做不了架构师?>>> java EE 5配置QQ企业邮件发送 1.在项目的WebRoot/META-INF/新建context.xml 具体内容如下: &l ...
- 【开源】java做游戏之QQ连连看java单机高仿版(算是目前最高仿的了)
QQ连连看JAVA高仿单机版V1.0 前言 为什么说是目前最高仿的呢,因为想做这个的一般是新手,要实现的跟我一样有点难度,至少我在网上没搜到(java版本).还有就是高手对这个没兴趣,不会做这个玩意儿 ...
- QQ好友列表导出用JTree树实现
最近学习了一下JTree的使用方法:QQ好友列表导出用JTree树实现 先来看一下树的实例: 构建一个树, DefaultMutableTreeNode root = new DefaultMutab ...
- Java TCP实现高仿版QQ聊天(二)
前言 这是在上一篇博客基础上开展的,第一部分我们只实现了本机的聊天,无法将程序放置另外机器上和本机进行聊天.这篇博客我将介绍如何实现不同机器之间实现聊天,达到真正意义上的聊天.不过这篇博客在其他机 ...
- java 判断qq_Java检测QQ是否在线状态
腾讯QQ在线状态 WEB 服务Endpoint:http://www.webxml.com.cn/webservices/qqOnlineWebService.asmxDisco:http://www ...
- jenkins之qq企业邮箱配置
一.配置qq企业邮箱 1.登录jenkins后台管理,选择 系统管理 ☞ 系统设置 2.SMTP server配置 3.邮件通知配置 配置ssl等参数 点击 高级 4.发送邮件测试 总结:邮箱配置 ...
最新文章
- 分享Kali Linux 2016.2第46周虚拟机
- SQL Server 2012 Managed Service Account
- 蓝桥杯-题目:猜算式
- 浅析分布式数据库中间件DDM
- 中考数学不准使用计算机,中考数学蒙题技巧
- Linq(筛选与排序)
- sublime 3 3083验证码
- torch.utils.data.DataLoader 详解
- Java的clone方法
- 客户端考试之渐进增强与优雅降级
- jdbc mysql innodb 死锁 deadlock_Mysql InnoDB 数据更新/删除导致锁表
- python3x菜鸟教程_菜鸟教程python3
- html组件做成圆角,css3制作圆角按钮
- idea activation code记录
- AXI 基础第 4 讲 - 使用 AXI VIP 作为 AXI4 主接口的协议检查工具
- PIC16F877A第一个程序
- Android 更换壁纸 代码
- 开局一张图帮你充分理解哈希表(散列表)
- python中Excel表的读写改详解
- 特征工程之One-Hot编码、label-encoding、自定义编码