Compress directory to tar.gz with Commons Compress

后端 未结 6 1406
终归单人心
终归单人心 2020-12-30 06:13

I\'m running into a problem using the commons compress library to create a tar.gz of a directory. I have a directory structure that is as follows.

parent/
          


        
6条回答
  •  不知归路
    2020-12-30 06:39

    Check below for Apache commons-compress and File walker examples.

    This example tar.gz a directory.

    public static void createTarGzipFolder(Path source) throws IOException {
    
            if (!Files.isDirectory(source)) {
                throw new IOException("Please provide a directory.");
            }
    
            // get folder name as zip file name
            String tarFileName = source.getFileName().toString() + ".tar.gz";
    
            try (OutputStream fOut = Files.newOutputStream(Paths.get(tarFileName));
                 BufferedOutputStream buffOut = new BufferedOutputStream(fOut);
                 GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(buffOut);
                 TarArchiveOutputStream tOut = new TarArchiveOutputStream(gzOut)) {
    
                Files.walkFileTree(source, new SimpleFileVisitor<>() {
    
                    @Override
                    public FileVisitResult visitFile(Path file,
                                                BasicFileAttributes attributes) {
    
                        // only copy files, no symbolic links
                        if (attributes.isSymbolicLink()) {
                            return FileVisitResult.CONTINUE;
                        }
    
                        // get filename
                        Path targetFile = source.relativize(file);
    
                        try {
                            TarArchiveEntry tarEntry = new TarArchiveEntry(
                                    file.toFile(), targetFile.toString());
    
                            tOut.putArchiveEntry(tarEntry);
    
                            Files.copy(file, tOut);
    
                            tOut.closeArchiveEntry();
    
                            System.out.printf("file : %s%n", file);
    
                        } catch (IOException e) {
                            System.err.printf("Unable to tar.gz : %s%n%s%n", file, e);
                        }
    
                        return FileVisitResult.CONTINUE;
                    }
    
                    @Override
                    public FileVisitResult visitFileFailed(Path file, IOException exc) {
                        System.err.printf("Unable to tar.gz : %s%n%s%n", file, exc);
                        return FileVisitResult.CONTINUE;
                    }
    
                });
    
                tOut.finish();
            }
    
        }
    

    This example extracts a tar.gz, and checks zip slip attack.

    public static void decompressTarGzipFile(Path source, Path target)
            throws IOException {
    
            if (Files.notExists(source)) {
                throw new IOException("File doesn't exists!");
            }
    
            try (InputStream fi = Files.newInputStream(source);
                 BufferedInputStream bi = new BufferedInputStream(fi);
                 GzipCompressorInputStream gzi = new GzipCompressorInputStream(bi);
                 TarArchiveInputStream ti = new TarArchiveInputStream(gzi)) {
    
                ArchiveEntry entry;
                while ((entry = ti.getNextEntry()) != null) {
    
                    Path newPath = zipSlipProtect(entry, target);
    
                    if (entry.isDirectory()) {
                        Files.createDirectories(newPath);
                    } else {
    
                        // check parent folder again
                        Path parent = newPath.getParent();
                        if (parent != null) {
                            if (Files.notExists(parent)) {
                                Files.createDirectories(parent);
                            }
                        }
    
                        // copy TarArchiveInputStream to Path newPath
                        Files.copy(ti, newPath, StandardCopyOption.REPLACE_EXISTING);
    
                    }
                }
            }
        }
    
        private static Path zipSlipProtect(ArchiveEntry entry, Path targetDir)
            throws IOException {
    
            Path targetDirResolved = targetDir.resolve(entry.getName());
    
            Path normalizePath = targetDirResolved.normalize();
    
            if (!normalizePath.startsWith(targetDir)) {
                throw new IOException("Bad entry: " + entry.getName());
            }
    
            return normalizePath;
        }
    

    References

    1. https://mkyong.com/java/how-to-create-tar-gz-in-java/
    2. https://commons.apache.org/proper/commons-compress/examples.html

提交回复
热议问题