zoukankan      html  css  js  c++  java
  • zip压缩文件(二)

    普通压缩文件以20M大小的文件为例

       public static void main(String[] args) {
            String source = "F:\demo\择天记 第5季 第01话 标清(270P).qlv";
            String zipFile = "F:\demo\zip\择天记.zip";
            zipFileNoBuffer(zipFile, source);
        }
    
        public static void zipFileNoBuffer(String zipFilePath, String sourceFilePath) {
            try {
                File zipFile = new File(zipFilePath);
                File sourceFile = new File(sourceFilePath);
                long length = sourceFile.length();
                System.out.println("开始压缩文件、文件大小:[" + formetFileSize(length) + "] ...");
                long beginTime = System.currentTimeMillis();
                ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
                InputStream input = new FileInputStream(sourceFile);
                zipOut.putNextEntry(new ZipEntry(sourceFile.getName()));
                int temp = 0;
                while ((temp = input.read()) != -1) {
                    zipOut.write(temp);
                }
                input.close();
                zipOut.closeEntry();
                zipOut.close();
                //时间耗时
                System.out.println("压缩完毕,耗时:[" + printTimeConsuming(beginTime) + "] ms ...");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    结果:

    Connected to the target VM, address: '127.0.0.1:49281', transport: 'socket'
    开始压缩文件、文件大小:[21.24M] ...
    压缩完毕,耗时:[68652] ms ...
    Disconnected from the target VM, address: '127.0.0.1:49281', transport: 'socket'
    

      

    利用缓冲区BufferInputStream 优化

     1   private static void firstZipFile(String zipFilePath, String sourceFilePath){
     2         try {
     3             File zipFile = new File(zipFilePath);
     4             File sourceFile = new File(sourceFilePath);
     5             long length = sourceFile.length();
     6             System.out.println("开始压缩文件、文件大小:[" + formetFileSize(length) + "] ...");
     7             long beginTime = System.currentTimeMillis();
     8             FileOutputStream fileOut = new FileOutputStream(zipFile);
     9             ZipOutputStream zipOut = new ZipOutputStream(fileOut);
    10             BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(zipOut);
    11             InputStream input = new FileInputStream(sourceFile);
    12             BufferedInputStream bufferedInputStream = new BufferedInputStream(input);
    13             zipOut.putNextEntry(new ZipEntry(sourceFile.getName()));
    14             int temp = 0;
    15             while ((temp = bufferedInputStream.read()) != -1) {
    16                 bufferedOutputStream.write(temp);
    17             }
    18             bufferedInputStream.close();
    19             input.close();
    20             bufferedOutputStream.close();
    21             zipOut.close();
    22             fileOut.close();
    23             //时间耗时
    24             System.out.println("压缩完毕,耗时:[" + printTimeConsuming(beginTime) + "] ms ...");
    25         } catch (Exception e) {
    26             e.printStackTrace();
    27         }
    28     }

    结果:耗时缩短了(68652-2501)毫秒

    Connected to the target VM, address: '127.0.0.1:51524', transport: 'socket'
    开始压缩文件、文件大小:[21.24M] ...
    压缩完毕,耗时:[2501] ms ...
    Disconnected from the target VM, address: '127.0.0.1:51524', transport: 'socket'
    

     说明:

    这是一个调用本地方法与原生操作系统进行交互,从磁盘中读取数据。每读取一个字节的数据就调用一次本地方法与操作系统交互,是非常耗时的。例如我们现在有30000个字节的数据,如果使用FileInputStream那么就需要调用30000次的本地方法来获取这些数据,而如果使用缓冲区的话(这里假设初始的缓冲区大小足够放下30000字节的数据)那么只需要调用一次就行。因为缓冲区在第一次调用read()方法的时候会直接从磁盘中将数据直接读取到内存中。随后再一个字节一个字节的慢慢返回。

    第二次优化:

     1 /**
     2      * 第二次优化使用 Channel
     3      */
     4     private static void secondZipFile(String zipFilePath, String sourceFilePath ){
     5         try {
     6             File zipFile = new File(zipFilePath);
     7             File sourceFile = new File(sourceFilePath);
     8             long length = sourceFile.length();
     9             System.out.println("开始压缩文件、文件大小:[" + formetFileSize(length) + "] ...");
    10             long beginTime = System.currentTimeMillis();
    11             FileOutputStream fileOut = new FileOutputStream(zipFile);
    12             ZipOutputStream zipOut = new ZipOutputStream(fileOut);
    13             WritableByteChannel writableByteChannel = Channels.newChannel(zipOut);
    14             FileInputStream input = new FileInputStream(sourceFile);
    15             FileChannel channel =  input.getChannel();
    16             zipOut.putNextEntry(new ZipEntry(sourceFile.getName()));
    17             channel.transferTo(0, length, writableByteChannel);
    18             channel.close();
    19             input.close();
    20             writableByteChannel.close();
    21             zipOut.close();
    22             fileOut.close();
    23             //时间耗时
    24             System.out.println("压缩完毕,耗时:[" + printTimeConsuming(beginTime) + "] ms ...");
    25         } catch (Exception e) {
    26             e.printStackTrace();
    27         }
    28     }

    结果:比第一次优化耗时缩短了(2501-1810)毫秒

    Connected to the target VM, address: '127.0.0.1:52021', transport: 'socket'
    开始压缩文件、文件大小:[21.24M] ...
    压缩完毕,耗时:[1810] ms ...
    Disconnected from the target VM, address: '127.0.0.1:52021', transport: 'socket'
    

      

  • 相关阅读:
    [C++ Primer Plus] 第9章、内存模型和名称空间(二)课后习题
    [C++ Primer Plus] 第9章、内存模型和名称空间(一)程序清单
    [c/c++] programming之路(28)、结构体存储和内存对齐+枚举类型+typedef+深拷贝和浅拷贝
    [c/c++] programming之路(27)、union共用体
    [c/c++] programming之路(26)、结构体
    opencv学习之路(37)、运动物体检测(二)
    [Python]基础教程(4)、Python 变量类型
    opencv学习之路(36)、运动物体检测(一)
    opencv学习之路(35)、SURF特征点提取与匹配(三)
    opencv学习之路(34)、SIFT特征匹配(二)
  • 原文地址:https://www.cnblogs.com/lxn0216/p/12509721.html
Copyright © 2011-2022 走看看