文章目录

  • 写在前面
  • 使用Buffered缓冲流压缩
  • 使用nio的FileChannel压缩
  • 使用apache.commons包下的并行压缩方式压缩

写在前面

对于大文件批量压缩的问题,实际上是非常消耗时间的,怎么能提高压缩速度呢?
在这里提供了三种方式压缩文件,咱们对比一下哪一个压缩速度更快。

在这里提供了三个文件,压缩后的大小大概是1.1GB左右,咱们测试一下每一种压缩方式的压缩时间。

使用Buffered缓冲流压缩

    /*** zip文件压缩* @param inputFile 待压缩文件夹/文件名* @param outputFile 生成的压缩包名字*/public static void ZipCompress(String inputFile, String outputFile) throws Exception {//创建zip输出流ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputFile));//创建缓冲输出流BufferedOutputStream bos = new BufferedOutputStream(out);File input = new File(inputFile);compress(out, bos, input,null);bos.close();out.close();}/*** @param name 压缩文件名,可以写为null保持默认*///递归压缩public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException {if (name == null) {name = input.getName();}//如果路径为目录(文件夹)if (input.isDirectory()) {//取出文件夹中的文件(或子文件夹)File[] flist = input.listFiles();if (flist.length == 0)//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入{out.putNextEntry(new ZipEntry(name + "/"));} else//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩{for (int i = 0; i < flist.length; i++) {compress(out, bos, flist[i], name + "/" + flist[i].getName());}}} else//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中{out.putNextEntry(new ZipEntry(name));FileInputStream fos = new FileInputStream(input);BufferedInputStream bis = new BufferedInputStream(fos);int len;//将源文件写入到zip文件中byte[] buf = new byte[1024];while ((len = bis.read(buf)) != -1) {bos.write(buf,0,len);}bis.close();fos.close();}}public static void main(String[] args) {try {//压缩System.out.println("开始压缩");long date = new Date().getTime();ZipCompress("D:\\fileTest", "D:\\TestbyYTT.zip");System.out.println("压缩结束用时" + (new Date().getTime() - date));} catch (Exception e) {e.printStackTrace();}}

执行了三次,结果如下:
开始压缩
压缩结束用时46835开始压缩
压缩结束用时48016开始压缩
压缩结束用时47280

结论:平均就是47秒左右。

使用nio的FileChannel压缩

    /*** NIO方式压缩*/public static File fileToZip(String sourceFilePath, String zipFilePath, String fileName) throws IOException {File sourceFile = new File(sourceFilePath);FileInputStream fis = null;BufferedInputStream bis = null;FileOutputStream fos = null;ZipOutputStream zos = null;WritableByteChannel writableByteChannel = null;File zipFile = new File(zipFilePath + "/" + fileName);if (!sourceFile.exists()) {System.out.println("待压缩的文件目录:" + sourceFilePath + "不存在.");} else {try {if (zipFile.exists()) {Files.delete(zipFile.toPath());}File[] sourceFiles = sourceFile.listFiles();if (null == sourceFiles || sourceFiles.length < 1) {System.out.println("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");} else {fos = new FileOutputStream(zipFile);zos = new ZipOutputStream(new BufferedOutputStream(fos));writableByteChannel = Channels.newChannel(zos) ;for (File file : sourceFiles) {//创建ZIP实体,并添加进压缩包ZipEntry zipEntry = new ZipEntry(file.getName());zos.putNextEntry(zipEntry);//读取待压缩的文件并写进压缩包里fis = new FileInputStream(file);FileChannel fileChannel = fis.getChannel();fileChannel.transferTo(0, file.length() -1,writableByteChannel);}}} finally {//关闭流if (null != bis) {bis.close();}if (fis != null) {fis.close();}if (zos != null) {zos.close();}if (fos != null) {fos.close();}if (null != writableByteChannel) {writableByteChannel.close();}}}return zipFile;}
执行了三次,结果如下:
开始压缩
压缩结束用时36929开始压缩
压缩结束用时37783开始压缩
压缩结束用时36246

结论:平均36秒左右。
注意!transferTo方法最大能读取2G的文件!

使用apache.commons包下的并行压缩方式压缩

   /*** @param sourceFilePath 需要压缩的目录* @param zipOutName 压缩后的文件名称**/public static void compressFileList(String sourceFilePath, String zipOutName) throws IOException, ExecutionException, InterruptedException {File sourceFile = new File(sourceFilePath);File[] sourceFiles = sourceFile.listFiles();ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("compressFileList-pool-").build();ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20), factory);ParallelScatterZipCreator parallelScatterZipCreator = new ParallelScatterZipCreator(executor);OutputStream outputStream = new FileOutputStream(zipOutName);ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(outputStream);zipArchiveOutputStream.setEncoding("UTF-8");for (File inFile : sourceFiles) {final InputStreamSupplier inputStreamSupplier = () -> {try {return new FileInputStream(inFile);} catch (FileNotFoundException e) {e.printStackTrace();return new NullInputStream(0);}};ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(inFile.getName());zipArchiveEntry.setMethod(ZipArchiveEntry.DEFLATED);zipArchiveEntry.setSize(inFile.length());zipArchiveEntry.setUnixMode(UnixStat.FILE_FLAG | 436);parallelScatterZipCreator.addArchiveEntry(zipArchiveEntry, inputStreamSupplier);}parallelScatterZipCreator.writeTo(zipArchiveOutputStream);zipArchiveOutputStream.close();outputStream.close();System.out.println("ParallelCompressUtil->ParallelCompressUtil-> info:{}"+ JSONObject.toJSONString(parallelScatterZipCreator.getStatisticsMessage()));}
执行了三次,结果如下:
开始压缩
ParallelCompressUtil->ParallelCompressUtil-> info:{}{"compressionElapsed":22642,"mergingElapsed":3802}
压缩结束用时27261开始压缩
ParallelCompressUtil->ParallelCompressUtil-> info:{}{"compressionElapsed":21958,"mergingElapsed":3406}
压缩结束用时25524开始压缩
ParallelCompressUtil->ParallelCompressUtil-> info:{}{"compressionElapsed":22076,"mergingElapsed":3668}
压缩结束用时25977

结论:平均26秒左右。

使用java压缩文件成zip——三种方式压缩文件速度对比相关推荐

  1. sass文件编译的三种方式【舒】

    [舒:]sass文件编译的三种方式 方式一: 1.webstorm打开evtGulp项目或者mcake-activity项目 2.中,开启gulp->default/develop,启动watc ...

  2. Java中实现接口的三种方式您造吗?

    本文介绍了Java中实现接口的三种方式:常规实现方式.匿名内部类和 Lambda表达式实现方式.希望已经了解的同学可以重新温习一下,不了解的同学则从中受益! Java中接口最常规的实现方式 同学们都会 ...

  3. 用python打开文件夹的三种方式

    用python打开文件夹的三种方式 一.利用explorer.exe import os# 利用explorer.exe执行 start_directory = r'C:\代码\软件包' os.sys ...

  4. java中实现多线程的三种方式

    java中实现多线程的三种方式 1.实现多线程的方法: 在java中实现多线程的两途径:继承Thread类,实现Runable接口(Callable) 2.继承Thread类实现多线程: ​ 继承类T ...

  5. java中Map遍历的三种方式

    Java中Map遍历的三种方式 前言 一:在for循环中使用entries实现Map的遍历: 二:在for循环中遍历key或者values,一般适用于只需要map中的key或者value时使用,在性能 ...

  6. Java 创建一个线程的三种方式

    Java 创建一个线程的三种方式 更多内容,点击了解: https://how2j.cn/k/thread/thread-start/353.html 创建多线程有3种方式,分别是继承线程类,实现Ru ...

  7. java连接access数据库的三种方式以及远程连接

    连接access数据库,网上的内容很多,尝试的过程中也会遇到各种问题,没有特别好的介绍,所以自己想总结一下,日后备用. 这里需要提前说明下,win7系统32bit和64bit默认安装的access都是 ...

  8. java实现线程安全的三种方式

    前言 一个程序在运行起来的时候会转换成进程,通常含有多个线程.通常情况下,一个进程中的比较耗时的操作(如长循环.文件上传下载.网络资源获取等),往往会采用多线程来解决. 比如现实生活中,银行取钱问题. ...

  9. Java 实现 HTTP 请求的三种方式

    除了本文推荐的几种方式,强烈推荐 OkHttp 目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较 ...

  10. java实现HTTP请求的三种方式

    From: https://www.cnblogs.com/hhhshct/p/8523697.html 目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的 ...

最新文章

  1. ios警告与提示对话框
  2. 【Linux】一步一步学Linux——dpkg-deb命令(270)
  3. Dependency injection in .NET Core的最佳实践
  4. 看完此文再不懂区块链算我输:手把手教你用Python从零开始创建区块链
  5. 【转】在.Net中关于AOP的实现
  6. php 单例模式有什么缺点_PHP的完整形式是什么?
  7. Flutter 中的国际化之多语言环境
  8. camel Java to xml_java – 当Camel从XML文件加载路由时,在注册表中找不到Bean
  9. Assets和Raw区别
  10. Latex 同时使用中英文双语图表名称(中英文双标题)+更改图表冒号为空格
  11. [DirectShow] 033 - Using Windowed Mode
  12. [USACO 4.2.2] The Perfect Stall 完美的牛栏
  13. 前端入门之(我与iscroll的不期而遇)
  14. 基于深度强化学习的车道线检测和定位(Deep reinforcement learning based lane detection and localization) 论文解读+代码复现
  15. python与医学统计_医学统计思维-数据库
  16. Uniapp-APP后台保活插件(安卓后台保活)
  17. tableau-圆环图
  18. Arthas(阿尔萨斯)的基本使用
  19. html5编程色卡颜色,手把手教你制作手写色卡书签
  20. 厉害了,Github标星113K的前端学习路线图有中文版了

热门文章

  1. ​重磅:IBM以340亿美元收购红帽软件 或将成为云计算市场领军者
  2. 柳传志退休,联想的贸工技路线对错由后人评说
  3. 【OpenGL ES】着色语言GLSL
  4. 基于python提火车票信息_python3.X 抓取火车票信息【修正版】
  5. 过 DNF TP 驱动保护(二)
  6. JavaScript牛客面试题总结
  7. 智能安全帽-4G记录仪等移动视频图传系统里面的RTSP流输出的实现机制
  8. 某虚拟存储系统采用最近最少使用(LRU)页面淘汰算法,假定系统为每个作业分配4个页面的主存空间--软考系统架构设计师--不会做题?“猿”来绘个图解决吧
  9. 学而思pythonlevel3_【学而思网校语言学习】学而思网校【2019-寒】AE英语直播班 Level 3上【报价 价格 评测 怎么样】 -什么值得买...
  10. 上周四的复盘 | 市场回暖了?割肉吗?