JavaNIO实现ZIP解压

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/u013632755/article/details/80151421

对于ZIP文件的解压来说,NIO提供了一个默认的文件系统:ZipFileSystem,其父类是FileSystem。
通过如下代码,如果参数path指向的是一个zip或者jar文件,则就能获取ZipFileSystem的对象。

FileSystem fs = FileSystems.newFileSystem(path, null);

Files 进行文件操作

NIO的Files提供了诸多文件操作的函数,此处解压使用其copy、createDirectories、walkFileTree来实现。

  • static Path copy(Path from, Path to, CopyOption... options)
  • static Path copy(Path from, Path to, CopyOption... options)
    • 将from复制或移动到给定位置,并返回to。如果目标路径已经存在,那么复制或者移动将失败。如果想要覆盖已有的目标路径可以使用REPLACE_EXISTING选项。如果想要复制所有的文件属性,可以使用COPY_ATTRIBUTES选项。Files.copy(fromPath,toPath,StandardCopyOption.REPLACE_EXISTING,StandardCopyOption.COPY_ATTRIBUTES)
  • static Path createFile(Path path, FileAttribute<?>... attrs)
  • static Path createDirectory(Path path, FileAttribute<?>... attrs)
  • static Path createDirectories(Path path, FileAttribute<?>... attrs)
    • 创建一个文件或目录,createDirectorIes方法还会创建路径中所有的中间目录。

文件遍历

Files提供了walkFileTree来进行目录的子孙遍历:

  • static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
    • 便利给定路径的所有子孙,并将访问器应用于这些子孙上。

SimpleFileVisitor<T>:

  • static FileVisitResult visitFile(T path, BasicFileAttributes attrs)
    • 在访问文件或目录时被调用,返回CONTINUE、SKIP_SUBTREE、SKIP_SIBLINGS和TERMINATE之一,默认实现是不做任何操作而继续访问。
  • static FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
  • static FileVisitResult postVisitDirectory(T dir, BasicFileAttributes attrs)
    • 在访问目录之前和之后被调用,默认实现是不做任何操作而继续访问。
  • static FileVisitResult visitFileFailed(T path, IOException exc)
    • 如果在试图获取给定文件的信息时抛出异常,则该方法被调用。默认实现是重新抛出异常,这回导致访问操作以这个异常而终止。如果你想自己访问,可以覆盖这个方法。

ZIP解压

解压zip废话不多说代码如下:

public static void decompression(String fromPathStr, String targetPathStr) throws IOException {
    Path fromPath = Paths.get(fromPathStr);
    final Path targetPath = Paths.get(targetPathStr);
    FileSystem fs = FileSystems.newFileSystem(fromPath, null);
    long startTime = System.currentTimeMillis();
    Files.walkFileTree(fs.getPath("/"), new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            Files.copy(file, targetPath.resolve(file.toString().substring(1)), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
            if (dir.getParent() != null) {
                if (dir.getFileName().toString().equals("__MACOSX/")) { // MAC系统压缩自带的隐藏文件过滤
                    return FileVisitResult.SKIP_SUBTREE;
                }
                Files.createDirectories(targetPath.resolve(dir.toString().substring(1)));
            }

            return FileVisitResult.CONTINUE;
        }
    });
    long endTime = System.currentTimeMillis();
    LOG.info("解压文件花费时间:{}", endTime - startTime + " ms");
}

其他实现

maven添加依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>${commons.compress.version}</version>
</dependency>

代码:

public static void decompression(String fromPathStr, String targetPathStr) throws IOException {
    Long startTime = System.currentTimeMillis();
    ZipArchiveInputStream inputStream = new ZipArchiveInputStream(new BufferedInputStream(new FileInputStream(fromPathStr)));
    Files.createDirectories(Paths.get(targetPathStr));
    ZipArchiveEntry entry = null;
    while ((entry = inputStream.getNextZipEntry()) != null) {
        if (entry.isDirectory()) {
            Files.createDirectories(Paths.get(targetPathStr, entry.getName()));
        } else {
            OutputStream os = null;
            try {
                os = new BufferedOutputStream(new FileOutputStream(new File(targetPathStr, entry.getName())));
                //输出文件路径信息
                IOUtils.copy(inputStream, os);
            } finally {
                IOUtils.closeQuietly(os);
            }
        }
    }
    Long consumeTime = System.currentTimeMillis() - startTime;
    LOG.info("压缩文件花费时间:{}", consumeTime);
}

猜你喜欢

转载自blog.csdn.net/u013632755/article/details/80151421