FileUtil.java

/**
 * Copyright (c) 2016, All partners of the iTesla project (http://www.itesla-project.eu/consortium)
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * SPDX-License-Identifier: MPL-2.0
 */
package com.powsybl.commons.io;

import com.google.common.base.Preconditions;
import com.google.common.io.ByteSource;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Objects;

/**
 * @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
 */
public final class FileUtil {

    private FileUtil() {
    }

    public static void removeDir(Path dir) throws IOException {
        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                Files.delete(file);
                return super.visitFile(file, attrs);
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                Files.delete(dir);
                return super.postVisitDirectory(dir, exc);
            }
        });
    }

    public static void copyDir(Path source, Path dest) throws IOException {
        Files.walkFileTree(source, new CopyDirVisitor(source, dest, StandardCopyOption.REPLACE_EXISTING));
    }

    public static Path createDirectory(Path directory) {
        Objects.requireNonNull(directory);
        try {
            if (!Files.isDirectory(directory)) {
                Files.createDirectories(directory);
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }

        return directory;
    }

    private static class CopyDirVisitor extends SimpleFileVisitor<Path> {
        private final Path fromPath;
        private final Path toPath;
        private final CopyOption copyOption;

        public CopyDirVisitor(Path fromPath, Path toPath, CopyOption copyOption) {
            this.fromPath = fromPath;
            this.toPath = toPath;
            this.copyOption = copyOption;
        }

        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
            Path relativize = fromPath.relativize(dir);
            Path targetPath = toPath.resolve(relativize.toString());
            if (!Files.exists(targetPath)) {
                Files.createDirectory(targetPath);
            }
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
            Path relativize = fromPath.relativize(path);
            Files.copy(path, toPath.resolve(relativize.toString()), copyOption);
            return FileVisitResult.CONTINUE;
        }
    }

    /**
     * Simplistic implementation of byte source based on a {@link Path}, waiting for guava 21.
     * @param path
     * @param openOptions
     * @return
     */
    public static ByteSource asByteSource(Path path, OpenOption... openOptions) {
        Objects.requireNonNull(path);
        Preconditions.checkArgument(Files.isReadable(path), "Path %s is not readable.", path);
        return new ByteSource() {
            @Override
            public InputStream openStream() throws IOException {
                return Files.newInputStream(path, openOptions);
            }
        };
    }
}