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

nl.hsac.fitnesse.fixture.util.FileUtil Maven / Gradle / Ivy

There is a newer version: 5.3.17
Show newest version
package nl.hsac.fitnesse.fixture.util;

import org.apache.commons.lang3.StringUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.channels.FileChannel;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Scanner;

import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;

/**
 * File utilities.
 */
public final class FileUtil {
    private static final int BUFFER_SIZE = 4096;
    private static final String FILE_ENCODING = "UTF-8";

    private FileUtil() {
        // ensure no instance is made.
    }

    /**
     * Reads content of UTF-8 file on classpath to String.
     *
     * @param filename file to read.
     * @return file's content.
     * @throws IllegalArgumentException if file could not be found.
     * @throws IllegalStateException    if file could not be read.
     */
    public static String loadFile(String filename) {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        InputStream is = classLoader.getResourceAsStream(filename);
        if (is == null) {
            throw new IllegalArgumentException("Unable to locate: " + filename);
        }
        return streamToString(is, filename);
    }

    /**
     * Copies UTF-8 input stream's content to a string (closes the stream).
     *
     * @param inputStream input stream (UTF-8) to read.
     * @param fileName    description for stream in error messages.
     * @return content of stream
     * @throws RuntimeException if content could not be read.
     */
    public static String streamToString(InputStream inputStream, String fileName) {
        return streamToString(inputStream, fileName, null);
    }

    /**
     * Copies first  or all lines from UTF-8 input stream's content to a
     * string and closes the stream.
     *
     * @param is            input stream (UTF-8) to read.
     * @param name          description for stream in error messages.
     * @param numberOfLines number of lines to be read from input stream - if null, all lines are read
     * @return content of stream
     * @throws RuntimeException if content could not be read.
     */
    public static String streamToString(InputStream is, String name, Integer numberOfLines) {
        String result = null;
        try {
            try {
                if (numberOfLines == null) {
                    // read complete file into string
                    result = new Scanner(is, FILE_ENCODING).useDelimiter("\\A").next();
                } else {
                    // read only given number of lines
                    Scanner scanner = new Scanner(is, FILE_ENCODING);
                    int resultNrOfLines = 1;
                    result = "";
                    while (scanner.hasNext()) {
                        result = result + scanner.nextLine() + System.lineSeparator();
                        if (++resultNrOfLines > numberOfLines) {
                            break;
                        }
                    }
                    scanner.close();
                    if (result.isEmpty()) {
                        result = null;
                    }
                }
            } catch (java.util.NoSuchElementException e) {
                throw new IllegalStateException("Unable to read: " + name + ". Error: " + e.getMessage(), e);
            }
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                // what the hell?!
                throw new RuntimeException("Unable to close: " + name, e);
            }
        }
        return result;
    }

    /**
     * Copies source file to target.
     *
     * @param source source file to copy.
     * @param target destination to copy to.
     * @return target as File.
     * @throws IOException when unable to copy.
     */
    public static File copyFile(String source, String target) throws IOException {
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(source).getChannel();
            outputChannel = new FileOutputStream(target).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
        } finally {
            if (inputChannel != null) {
                inputChannel.close();
            }
            if (outputChannel != null) {
                outputChannel.close();
            }
        }
        return new File(target);
    }

    /**
     * Copy the contents of the given InputStream to the given OutputStream.
     * Closes both streams when done.
     *
     * @param in  the stream to copy from
     * @param out the stream to copy to
     * @return the number of bytes copied
     * @throws java.io.IOException in case of I/O errors
     */
    public static int copy(InputStream in, OutputStream out) throws IOException {
        try {
            int byteCount = 0;
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead = -1;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
                byteCount += bytesRead;
            }
            out.flush();
            return byteCount;
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
            try {
                out.close();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    /**
     * Writes content to file, in UTF-8 encoding.
     *
     * @param filename file to create or overwrite.
     * @param content  content to write.
     * @return file reference to file.
     */
    public static File writeFile(String filename, String content) {
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(filename, FILE_ENCODING);
            pw.write(content);
            pw.flush();
        } catch (FileNotFoundException e) {
            throw new IllegalArgumentException("Unable to write to: " + filename, e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } finally {
            if (pw != null) {
                pw.close();
            }
        }
        return new File(filename);
    }

    public static File writeFromScanner(String filename, Scanner sc) {
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(filename, FILE_ENCODING);

            while (sc.hasNextLine()) {
                String next = sc.nextLine();
                pw.write(next + System.getProperty("line.separator"));
            }
        } catch (FileNotFoundException e) {
            throw new IllegalArgumentException("Unable to write to: " + filename + ".tmp", e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } finally {
            if (pw != null) {
                pw.flush();
                pw.close();
            }
        }
        return new File(filename);
    }

    /**
     * Saves byte[] to new file.
     *
     * @param baseName  name for file created (without extension),
     *                  if a file already exists with the supplied name an
     *                  '_index' will be added.
     * @param extension extension for file.
     * @param content   data to store in file.
     * @return absolute path of created file.
     */
    public static String saveToFile(String baseName, String extension, byte[] content) {
        String result;
        File output = determineFilename(baseName, extension);
        FileOutputStream target = null;
        try {
            target = new FileOutputStream(output);
            target.write(content);
            result = output.getAbsolutePath();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (target != null) {
                try {
                    target.close();
                } catch (IOException ex) {
                    // what to to?
                }
            }
        }
        return result;
    }

    public static File determineFilename(String baseName, String extension) {
        if (!StringUtils.isEmpty(extension)) {
            extension = "." + extension;
        }
        File output = new File(baseName + extension);
        // ensure directory exists
        File parent = output.getAbsoluteFile().getParentFile();
        if (!parent.exists()) {
            if (!parent.mkdirs()) {
                throw new IllegalArgumentException(
                        "Unable to create directory: "
                                + parent.getAbsolutePath());
            }
        }
        int i = 0;
        // determine first filename not yet in use.
        while (output.exists()) {
            i++;
            String name = String.format("%s_%s%s", baseName, i, extension);
            output = new File(name);
        }
        return output;
    }

    /**
     * Determines a file's relative path related to a base directory (a parent some levels up in the tree).
     *
     * @param base  base directory.
     * @param child file to get relative path for.
     * @return relative path.
     */
    public static String getRelativePath(String base, String child) {
        return new File(base).toURI().relativize(new File(child).toURI()).getPath();
    }

    /**
     * Appends the extra content to the file, in UTF-8 encoding.
     * @param filename  file to create or append to.
     * @param extraContent   extraContent to write.
     * @param onNewLine whether a new line should be created before appending the extra content
     * @return file reference to file.
     */
    public static File appendToFile(String filename, String extraContent, boolean onNewLine){
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(
                    new BufferedWriter(
                            new OutputStreamWriter(
                                    new FileOutputStream(filename, true),
                                    FILE_ENCODING)
                    )
            );
            if (onNewLine) {
                pw.println();
            }
            pw.print(extraContent);
        } catch (FileNotFoundException e) {
            throw new IllegalArgumentException("Unable to write to: " + filename, e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } finally {
            if (pw != null) {
                pw.close();
            }
        }
        return new File(filename);
    }

    /**
     * Deletes file (or directory recursively).
     * Does not throw error if file does not exist.
     * @param f file/directory to be deleted
     * @return true if f no longer exists (independent of whether it existed beforehand).
     */
    public static boolean delete(File f) {
        if (f.isDirectory()) {
            for (File c : f.listFiles()) {
                delete(c);
            }
        }
        f.delete();
        return !f.exists();
    }

    /**
     * Copies source directory to target, recursively.
     * @param source source directory
     * @param target target, must not exist yet.
     */
    public static void copyTree(String source, String target) {
        Path sourcePath = Paths.get(source);
        Path targetPath = Paths.get(target);
        try {
            Files.walkFileTree(sourcePath, new SimpleFileVisitor() {
                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    Files.createDirectories(resolveTarget(dir));
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.copy(file, resolveTarget(file), COPY_ATTRIBUTES);
                    return FileVisitResult.CONTINUE;
                }

                private Path resolveTarget(Path file) {
                    return targetPath.resolve(sourcePath.relativize(file));
                }
            });
        } catch (IOException e) {
            throw new RuntimeException("Unable to copy tree", e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy