解压后文件名乱码

由于zip格式文件无编码存储的结构,因此解压时无法知道原先的编码。

当解压zip格式文件时使用的编码和原编码不一致时,就可能会出现解压后文件名乱码问题。

猜测编码

基于上述问题,需要对zip格式文件所使用的编码进行猜测。

笔者使用基于统计学原理的 juniversalchardet 库来猜测编码,下面是maven依赖坐标。

<dependency>
<groupId>com.googlecode.juniversalchardet</groupId>
<artifactId>juniversalchardet</artifactId>
<version>1.0.3</version>
</dependency>

下面是一个简单的例子,只需要提供待猜测文本的字节数据即可。

UniversalDetector detector = new UniversalDetector(null);
String text = "这是一段测试文本";
byte[] buf = text.getBytes("GB18030");
detector.handleData(buf, 0, buf.length);
detector.dataEnd();
System.out.println(detector.getDetectedCharset()); // GB18030

zip格式文件结构

zip格式文件的结构如下(具体解析见其他文章),这里需要其中的 CENTRAL_DIRCETORY_HEADER 区域,该区域存储zip里所有的文件及文件夹的名称。

|LOCAL_FILE_HEADER|
|EXTRA_LOCAL_HEADER|
|CENTRAL_DIRCETORY_HEADER|
|END_OF_CENTRAL_DIRCETORY_RECORD|

利用Apache Compress库获取名称字节数据

笔者一般推荐使用 Apache Compress 库来处理zip格式文件,可以使用 ZipArchiveEntry.getRawName 方法来获取名称的字节数据。

下面是检测zip格式文件编码的例子,其中为了加快速度忽略解析Local file header区域。

public String detectCharset(File file) throws IOException {
// Ignore resolve local file header to improve rate.
ZipFile zipFile = new ZipFile(file, StandardCharsets.UTF_8.name(), true, false);
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
UniversalDetector detector = new UniversalDetector(null); while (entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
byte[] buf = entry.getRawName(); // Get the byte data of file name.
detector.handleData(buf, 0, buf.length);
}
detector.dataEnd();
return detector.getDetectedCharset();
}

下面是Apache Compress库的依赖坐标。

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>

注意事项

数据量越大 juniversalchardet 库检测编码就越准确,反之可能得到空结果或者不准确的编码。

例如猜测编码章节中让 text="中文" ,最后输出的结果是 KOI8-R

为此实际使用中要根据业务场景来做限定,比方说系统面向的用户只可能是中文用户,那么当出现 KOI8-R 这种斯拉夫文字的编码时应当限定为中文的 GB18030 编码(数据量小时GB18030非常大概率会被检测成KOI8-R)。

zip格式文件编码检测的更多相关文章

  1. 文件编码检测.ZC一些资料(包含java的)

    1.IMultiLanguage3 或者 IMultiLanguage2 1.1.怎么判断XML 的编码格式(UTF-8或GB2312等)-CSDN论坛.html(https://bbs.csdn.n ...

  2. Linux下zip格式文件的解压缩和压缩

    Linux下zip格式文件的解压缩和压缩 Linux下的软件包很多都是压缩包,软件的安装就是解压缩对应的压缩包.所以,就需要熟练使用常用的压缩命令和解压缩命令.最常用的压缩格式有.tar.gz/tgz ...

  3. java压缩/解压缩zip格式文件

    因为项目要用到压缩.解压缩zip格式压缩包,只好自己封装一个,对于网上流行的中文乱码的问题,本文的解决方法是用apache的包代替jdk里的.基本上还是比较好用的. 废话少说,直接上代码. }     ...

  4. 文件编码检测.ZC

    1.今天(20181101) 发现 g文件中的 xml头 和 文件编码不一致,最后发现 貌似是我搞错了,人家的文件 编码方式写的是对的. 我发现的现象是:XML里面写的是"GBK" ...

  5. 使用C#压缩解压rar和zip格式文件

    为了便于文件在网络中的传输和保存,通常将文件进行压缩操作,常用的压缩格式有rar.zip和7z,本文将介绍在C#中如何对这几种类型的文件进行压缩和解压,并提供一些在C#中解压缩文件的开源库. 在C#. ...

  6. 下载zip格式文件(压缩Excel文件为zip格式)

    Mongodb配置文件参考这一篇:http://www.cnblogs.com/byteworld/p/5913061.html package util; import java.io.Buffer ...

  7. LearnPython - Zip格式文件的解压缩

    import zipfile import os def unzip(zip_name, target_dir): files = zipfile.ZipFile(zip_name) for zip_ ...

  8. 关于springmvc下服务器文件打包成zip格式下载功能

    关于springmvc下服务器文件打包成zip格式下载功能 2016年09月21日 11:22:14 toxic_guantou 阅读数:5731更多 个人分类: 技术点存储   版权声明:本文为博主 ...

  9. Eclipse设置软tab(用4个空格字符代替)及默认utf-8文件编码(unix)

    简单配置版本: Eclipse設置 一.window->Preferences-> General-Editors->Text Editors , 右边勾选insert spaces ...

随机推荐

  1. Spring 源码(6)BeanFactoryPostProcessor怎么执行的?

    上一篇文章 https://www.cnblogs.com/redwinter/p/16167214.html 解读了如何进行自定义属性值的编辑器的解析器,并且还介绍了BeanFactory的准备过程 ...

  2. Protobuf在Python中的应用(序列化数据)

    1.了解Protobuf Protocol Buffer是Google的语言中立的,平台中立的,可扩展机制的,用于序列化结构化数据 - 对比XML,但更小,更快,更简单.您可以定义数据的结构化,然后可 ...

  3. Springboot 整合 MyBatisPlus[详细过程]

    Springboot 整合 MyBatisPlus[详细过程] 提要 这里已经将Springboot环境创建好 这里只是整合MyBatis过程 引入Maven依赖 添加MyBatisPlus启动依赖, ...

  4. 数据库界的Swagger:一键生成数据库文档!

    对于开发的API文档,我们可以通过Swagger等工具来自动生成了.但是对于数据库表结构的文档呢,在实际开发中在开发前我们一般会先设计好表结构,大家讨论一下, 这个时候就很需要有个数据库表结构的文档, ...

  5. C# 随机给一个全部信息都未知的类类型,如何获取该类的类名、属性个数、属性名、属性的数据类型、属性值?

    一.场景假设 假设现在有一个泛型类T的实例对象t,该T类的全部信息都未知. 要求:打印输出实例对象t的类名.属性个数.属性名.属性的数据类型.属性值. 二.解决问题 1.我们根据输出的内容要求定义一个 ...

  6. django-rest-framework 基础三 认证、权限和频率

    django-rest-framework 基础三 认证.权限和频率 目录 django-rest-framework 基础三 认证.权限和频率 1. 认证 1.1 登录接口 1.2 认证 2. 权限 ...

  7. JUC自定义线程池练习

    JUC自定义线程池练习 首先上面该线程池的大致流程 自定义阻塞队列 首先定义一个双向的队列和锁一定两个等待的condition 本类用lock来控制多线程下的流程执行 take和push方法就是死等, ...

  8. layui数据表格导入数据

    作为一个后端程序员,前端做的确实很丑,所以就学习了一下layui框架的使用.数据表格主要的问题就是传输数据的问题,这里我用我的前后端代码来做一个实际的分解. 前端部分 可以到layui官网示例中找到数 ...

  9. 面试官:BIO、NIO、AIO是什么,他们有什么区别?

    哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,感觉上次的公司氛围不 ...

  10. MySQL 事务常见面试题总结 | JavaGuide 审核中

    <Java 面试指北>来啦!这是一份教你如何更高效地准备面试的小册,涵盖常见八股文(系统设计.常见框架.分布式.高并发 ......).优质面经等内容. 本文原发于 MySQL知识点&am ...