All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.broadinstitute.hellbender.utils.ZipUtils Maven / Gradle / Ivy

The newest version!
package org.broadinstitute.hellbender.utils;

import org.apache.commons.io.IOUtils;
import org.broadinstitute.hellbender.engine.GATKPath;
import org.broadinstitute.hellbender.exceptions.GATKException;
import org.broadinstitute.hellbender.exceptions.UserException;
import org.broadinstitute.hellbender.utils.gcs.BucketUtils;

import java.io.*;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.zip.*;

/**
 * Utility class to zip and unzip files.
 */
public class ZipUtils {

    /**
     * Unzips a file in a provided path into a destination directory.
     * @param path the location of the zip file to unzip.
     * @param dest the destination directory.
     * @param files files to unzip, by omission is the whole zip file content.
     */
    public static void unzip(final GATKPath path, final File dest, final String ... files) {
        Utils.nonNull(path, "the path provided cannot be null");
        Utils.nonNull(dest, "the destination directory provided cannot be null");
        Utils.validateArg((dest.isDirectory() || dest.mkdirs()) && dest.canWrite(), "could not create destination directory");
        final Predicate selected = composeSelectPredicate(files);
        try (final ZipInputStream in = new ZipInputStream(path.getInputStream())) {
            ZipEntry entry;
            while ((entry = in.getNextEntry()) != null) {
                if (selected.test(new File(entry.getName()))) {
                    final File entryDest = new File(dest, entry.getName());
                    if (entry.isDirectory()) {
                        entryDest.mkdirs();
                    } else {
                        final File parent = entryDest.getParentFile();
                        if (!parent.exists()) {
                            parent.mkdirs();
                        }
                        try (final FileOutputStream fos = new FileOutputStream(entryDest) ) {
                            IOUtils.copy(in, fos);
                        } catch (final IOException e) {
                            throw new GATKException("problems unzipping entry", e);
                        }
                    }
                }
            }
        } catch (final IOException ex) {
            throw new UserException.CouldNotReadInputFile(path.toString(), ex);
        }
    }

    /**
     * Creates a zip file give a source file/directory to zip and the final destination zip file path.\
     * 

* Directories are zipped recursively. *

* @param source the source folder or file. * @param dest the destination path. * @param files if not empty, this array indicate what files needs to be zipped. If zero length, all * files will be zipped. */ public static void zip(final File source, final GATKPath dest, final String ... files) { Utils.nonNull(source, "the destination directory provided cannot be null"); Utils.nonNull(dest, "the destination cannot be null"); if (source.isFile()) { if (files != null && files.length != 0) { throw new IllegalArgumentException("if the source is a regular file, you cannot specify a files to zip array"); } uncheckedZip(source.getParentFile(), dest, composeSelectPredicate(source.toString())); } else { final Predicate selection = composeSelectPredicate(files); uncheckedZip(source, dest, selection); } } /** * Performs the unzip action assuming inputs are correct. */ private static void uncheckedZip(final File sourceRoot, final GATKPath dest, final Predicate selection) { try (final ZipOutputStream out = new ZipOutputStream(dest.getOutputStream())) { final Deque pending = new ArrayDeque<>(); final String prefix = sourceRoot.toString() + File.separator; pending.addAll(Arrays.asList(sourceRoot.listFiles())); while (!pending.isEmpty()) { final File next = pending.removeFirst(); if (next.isFile()) { if (selection.test(next)) { final String relative = next.toString().replace(prefix, ""); out.putNextEntry(new ZipEntry(relative)); try (final FileInputStream nextIs = new FileInputStream(next)) { IOUtils.copy(nextIs, out); } out.closeEntry(); } } else if (next.isDirectory()) { final File[] children = next.listFiles(); for (int i = children.length - 1; i >= 0; i--) { pending.addFirst(children[i]); } } } } catch (final IOException ex) { throw new GATKException("errors trying to create zip file from " + sourceRoot + " to " + dest, ex); } } /** * Returns a predicate that returns {@code true} for entries present in the input array of {@code files} * @param files the target files. * @return never {@code null}. */ private static Predicate composeSelectPredicate(final String ... files) { if (files == null || files.length == 0) { return _x -> true; } else { final Set selected = Arrays.stream(files) .map(name -> new File(name).toPath().normalize().toFile()) .collect(Collectors.toSet()); return f -> selected.contains(f) || selected.contains(f.toPath().normalize().toFile()); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy