支持多平台下Zip的读取和解压问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

zip的悠久历史大家可以查下,这里讲下zip容易被忽略的知识。因为历史原因,ZIP的编码一般有两种,分别是CP437和UTF-8;这里zip的编码一般指zip里文件名的编码,文件内容的编码是原文件本身的编码,zip不会对文件内容编码做任何改版。原本文件名在不同操作系统下不一样,根据操作系统本身的编码有关。一般类Unix系统下默认是UTF-8,比如苹果系统、Linux.而windows系统下是GBK;如果zip编码只有两种,那windwos的GBK呢?那这个时候能正确读取吗

一、压缩后的文件名如何正确读取?

       这里要了解下字符集发展历史;CP437是EASCII的实现之一,Java里叫IBM437,后来又发展出了兼容部分CP437字符的ISO8859-1.而CP437和ISO8859-1作为EASCII的实现和扩展,都是单字节编码。

       zip压缩包本身没有字符集的标识,所以如何同时读取不同平台下的压缩的zip是一个问题;在实践中以ISO8859-1编码读取,因为单字节编码不会对原名称进行补码,所以不会引发解码异常;如果以UTF8读取其他字符集时会对文件名信息进行补码而造成改变,甚至引发解码异常。本文都是以apache compress为例

try (ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(inputStream, 
"ISO-8859-1")) {
                for (ZipArchiveEntry archiveEntry = zipInputStream.getNextZipEntry(); 
                      archiveEntry != null ; 
                        archiveEntry = zipInputStream.getNextZipEntry()) {

                           String archiveEntryName=decodeName(archiveEntry.getRawName());
                   }
}cathc(Exception e){

}

解码文件名

List<Charset>  charsets = Lists.newArrayList(StandardCharsets.UTF_8, Charset.forName("GBK"));
Charset nameCharset=null;
public String decodeName(byte[] bytes){
   if(nameCharset==null){
      for (Charset charset : charsets) {
       try {
         String name = charset.newDecoder()
                                .decode(ByteBuffer.wrap(nameBytes))
                                .toString();
         //对于拉丁语系的名称,第一次能解析出来
         //第二次遇到中文等其他语言就会乱码,所以其他碰到带有语言名称才保留字符集信息,避免重复解码
         if (name.getBytes("ISO8859-1").length != nameBytes.length) {
             nameCharset = charset;
           }
        return name;
      } catch (Exception e) {
        
     }
                      
   }
  }
 return new String(bytes,nameCharset);
}

二、如果正确读取内容?

byte[] bytes= new byte[(int) archiveEntry.getSize()];
zipInputStream.read(bytes);

String content=new String(bytes,"UTF-8");

一般我们采用上述方式读取,但是会有一下问题

               1.有些平台的工具不会把每个文件的大小信息放zip信息里,这个时候getSize()是-1;

               2.read的时候根据不同内存大小,不会全部读取到bytes里

               3.不同工具编辑后的文件内容的字符集可能差异很大

针对size不明的情况,只能以1字节读取。直到读取结果-1为止

ByteArrayOutputStream baos = new ByteArrayOutputStream();
 for (int b = zipInputStream.read(); b != -1;
       b = zipInputStream.read()) {
       baos.write(b);
    }
  baos.close();
byte[] bytes= baos.toByteArray();

针对不会一次性读取出来时,每次读取完都会返回当前读取的位置

byte[] bytes= new byte[(int) archiveEntry.getSize()];
   int offset = 0, len = bytes.length;
   for (int read; (read = zipInputStream.read(bytes, offset, len - offset)) > 0;
                             offset += read) {
 }

针对怎么识别字符集文本的问题,可以采用tika、icu4j等具体方法可以看下着两者api和包大小作取舍


总结

因为zip包特别大原因,不能直接加载到内存里或者解压再一个文件一个文件的读取。所以采用直接读取的方式。在读取的时候碰到文件中文报错,尝试过jdk的ZipFile、apache VFS2、apache comress。发现apache compress兼容性比较好且包比较小,遂采用,发现不同平台下报错,也通过测试和学习字符集知识了解到如何利用和规避异常以正确读取信息

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
猪猪家住宿管理系统,是基于O2O平台开发的一款简单实用的酒店客房和酒店客户管理系统,是全网络化酒店管理软件,充分结合中国酒店业的管理实情。系统界面简洁优美,操作直观简单,无需专门培训即可正常使用。普遍适用于中小型酒店宾馆、旅社、招待所、民宿等经营场所理想的自主管理软件。 猪猪家住宿管理系统优势: 1、配套住宿网站,前台管理软件能及时获取订单信息。 2、无纸化经营,自动发送短信替代手开押金单和入住单。 3、全网络版,多用户管理。 4、价格优惠,低于任何同款住宿管理软件收费的几倍。 5、入驻公司住宿网站,增强酒店宣传力度。 6、已住客人信息永久保存,下次入住直接查询办理入住。 7、酒店所有信息保存在云端,无需担心电脑死机,系统崩溃数据以及重要信息丢失的问题。 8、商家自主管理,随时更改酒店信息,网站实时显示。相当于你自己拥有了一个网站,自己管理自己的酒店。 9、运营统计以极快的速度详细完善统计出酒店的经营状况。   需要无纸化功能以及升级版软件(自动发送短信替代押金单、入住单、电子发票、短信提醒预订)的商家请加入技术群,咨询联系技术人员。 1.软件下载 任意打开一个浏览器,在浏览器搜索栏输入,猪猪家官方网站,点击主页下方的“管理软件下载”进入软件下载。注:为预防杀毒软件误杀软件,商家下载的时候尽量暂时关闭所有杀毒软件,方可正常下载安装。 2.软件安装 下载后的软件是一个名为 zhuzhujiaProjV1.zip 的压缩包,右键解压后,安装程序名为(猪猪家住宿管理系统)。 若安装程序的时候提示缺少.net framework 4.0运行环境,那就需要安装.net framework 4.0。 双击安装,一直点击下一步直至安装完成,安装时间最多10秒。安装完成后,桌面上会显示,双击打开 3.用户注册 打开登录界面后,使用商家酒店注册账号及密码登录系统,若商家没有登录账号和密码,点击新商家注册入口,完善信息,点击确定注册即可获得登录号和密码,账号为注册酒店全称,密码默认为联系电话(牢记登录账号和密码)。 填写信息应尽量准确。定位地图后,拖动图标标明酒店具体位置后,再点获取坐标,才能获取到酒店在地图上的坐标。(坐标很重要,方便顾客搜索查找酒店) 4.酒店登陆 双击桌面上的 猪猪家住宿管理系统 图标,进入登陆界面,输入帐号密码,点击登陆。 5.软件更新 每次打开软件时,会自动更新软件到最新版本。 6.软件卸载 在开始菜单中找到 卸载猪猪家住宿管理系统,点击即可。 7.系统功能界面介绍。 入住管理。 1普通入住(ctrl i):意为散客入住,非会员入住。住宿总价,自动计算出入住天数的总房费,不包含押金。若有两位客人同时入住一间房,要读取两人身份证,并添加到入住列表。完成所有信息录入,确认入住列表有两位客人信息后,点击确定办理入住 2会员入住(ctrl alt i):意为该酒店会员,可以点击会员入住通过余额支付的方式办理入住。 注:一张身份证不能同时登记多间房间。 3入住查询(ctrl shift i):通过搜索名字、身份证、电话号码可以查询到某个时间、某一间房或者全部房间客人的入住详细信息。 会员管理:分为添加会员(ctrl m)、管理会员(ctrl shift m)、查询会员(ctrl f)、会员充值、积分规则设置。 1添加会员(ctrl m):填写基本信息,成为该酒店会员。 2管理会员(ctrl shift m):对该酒店会员进行相应的操作。 3查询会员(ctrl f):通过该功能快捷查询到会员。 4积分规则设置:酒店可以设置会员消费多少元获得1积分,多少可以兑换免费住宿服务,也是酒店宣传营销的一种方式。   酒店管理 1修改酒店基本信息:在这里可以完善或者更改酒店的详细信息。 2运营统计:可以统计(日、月、年)的房间数量、总营业额、日均营业额、入住次数、日均入住次数、日均入住率。可以将统计数据导出为excel文件保存到电脑留存资料,也可以打印出来。统计15天的数据可以打印在一张A4纸上。当日报表统计当日的入住详情。 房间管理 1添加房间(ctrl r):按顺序填写房间编号、房间类型、房间价格、上传房间号对应照片(可暂时不上传图片),一个房间可以上传多张图片。(上传的图片必须是该房间对应的真实图片,保证上传的图片像素,取景可以多个角度拍摄,方便给网上客人一个直观的印象)。添加完一个房间可以继续添加下一个房间。房间类型可以在“设置”里添加。 2查找房间:可以输入房间号,定位到该房间号位置。(针对房间比较多的酒店)。按F5或者点击全部房间可以再次显示全部房间。 系统管理 1添加账号:酒店按照自身经营管理模式可以添加管理员或者前台账号。酒店管理员附加权限(基于酒店前台权限):①可以添加、删除、修改酒店管理员以及酒店前台账号。②可以修改或删除房间号。③可以设置会员积分规则。④对酒店会员进行管理。 2账号管理:删除或者修改管理员以及前台账号。 3字典设置:添加酒店房间类型。 4注销(ctrl L):注销当前登录账号,返回到登录界面。 5退出ctrl q:关闭软件。 预订功能 1线上预订:顾客通过猪猪网在线预订某个房间号后,酒店管理软件10秒钟左右会自动显示预订信息在界面左侧,同时被预订房间号会显示为绿色预订状态,商家可以选择对订单进行相应操作。 2线下预订:顾客通过电话预订或者到店预订房间,单击右键选择“预订”,老客户以及会员预订直接搜索查询顾客名字、身份证号码、电话号码办理入住。随意订:灵活操作预订,部限制身份证,适合通过电话预订方式的客户。 房态说明:空房显示为白色已打扫状态;入住显示为蓝色有客人状态;脏房显示为红色待打扫状态;预订显示为绿色暂未入住状态;超时为黄色,表示房间已经过了规定的入离时间;待续为紫色。 单击右键不同颜色房间号功能说明 1、右键单击白色 空房可以标记为脏房、办理会员/老客户入住、普客入住、预订、(编辑与删除为酒店管理员权限,前台无); 2、右键单击蓝色 入住房间可以修改入住信息、续住、退房; 3、右键单击红色 脏房可以标记为已打扫干净; 4、右键单击绿色 预订房间可以订单入住、退订; 5、右键单击黄色 超时房间可以修改入住信息、续住、退房; 6、右键单击紫色 待续房间可以修改入住信息、续住、退房;   常见问题说明 1、无法正常安装猪猪家住宿软件? ①缺少.netframework 4.0运行环境,那就需要安装DotNetFX40文件夹里的插件dotNetFx40_Full_x86_x64。②杀毒软件拦截安装程序运行,退出所有杀毒软件,再重新安装。③电脑版本太低,需升级电脑系统。注:软件运行的时候,建议退出杀毒软件。 2、登录密码或者账户忘记? 联系猪猪家技术人员咨询处理。 3、如何快速换房? 右键单击选中的房间号,选中“修改入住信息”,下拉房间号,选中另一房间号,完成后点击“修改入住信息并发送短信”即可办理换房。 4、办理入住登记完成,如何再次修改登记信息? 右键单击需要修改/删除的房间号,15分钟内可以修改/删除房间信息,超过15分钟无法删除信息,但是可以修改信息。 5、无法上传酒店图片? 上传图片默认为jpg格式不大于500k的图片,若图片过大或格式不正确,需修改后重新上传。   猪猪家住宿管理系统截图

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值