net.orzo.lib.Files.java Source code

Java tutorial

Introduction

Here is the source code for net.orzo.lib.Files.java

Source

/*
 * Copyright (C) 2014 Tomas Machalek
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.orzo.lib;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnsupportedCharsetException;
import java.util.NoSuchElementException;
import java.util.zip.GZIPInputStream;

import net.orzo.data.DirectoryReader;
import net.orzo.data.FilePairGenerator;
import net.orzo.data.FilePartReaderFactory;
import net.orzo.data.TwoGroupFilePairGenerator;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.io.input.ReversedLinesFileReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Defines a library of files-related functions available to JavaScript
 * environment.
 *
 * @author Tomas Machalek <tomas.machalek@gmail.com>
 */
public class Files {

    private static final Logger LOG = LoggerFactory.getLogger(Files.class);

    /**
     * Obtains an iterator which reads provided file (specified by path) line by
     * line. Iterator can be accessed by a classic method pair <i>hasNext()</li>
     * and <i>next()</i>.
     */
    public FileIterator<Object> fileReader(final String path, final String encoding) throws IOException {
        final LineIterator itr = FileUtils.lineIterator(new File(path), encoding);
        return new FileIterator<Object>() {

            @Override
            public boolean hasNext() {
                return itr.hasNext();
            }

            @Override
            public Object next() {
                return itr.nextLine(); // TODO wrapping???
            }

            @Override
            public void remove() {
                itr.remove();
            }

            public void close() {
                itr.close();
            }

            public String getPath() {
                if (File.separator.equals("/")) {
                    return path;

                } else {
                    return path.replace(File.separator, "/");
                }
            }
        };
    }

    public FileIterator<Object> reversedFileReader(final String path, final String encoding) throws IOException {
        return new FileIterator<Object>() {

            private ReversedLinesFileReader rlf = new ReversedLinesFileReader(new File(path), 1024 * 4, encoding);
            private String currLine = rlf.readLine();

            @Override
            public boolean hasNext() {
                return this.currLine != null;
            }

            @Override
            public Object next() {
                String ans;

                if (this.currLine != null) {
                    ans = this.currLine;
                    try {
                        this.currLine = this.rlf.readLine();

                    } catch (IOException ex) {
                        this.currLine = null;
                        throw new IllegalStateException(ex);
                    }
                    return ans;

                } else {
                    throw new NoSuchElementException();
                }
            }

            @Override
            public void close() {
                try {
                    this.currLine = null;
                    this.rlf.close();

                } catch (IOException e) {
                    throw new IllegalStateException(e);
                }
            }

            @Override
            public String getPath() {
                return path;
            }
        };
    }

    public FileIterator<Object> gzipFileReader(final String path, final String encoding) throws IOException {
        try {
            final GZIPInputStream gis = new GZIPInputStream(new FileInputStream(path));
            final Reader reader = new InputStreamReader(gis, encoding);
            return new FileIterator<Object>() {

                private final BufferedReader br = new BufferedReader(reader);
                private String currLine = br.readLine();

                @Override
                public boolean hasNext() {
                    return this.currLine != null;
                }

                @Override
                public Object next() {
                    String ans;

                    if (this.currLine != null) {
                        ans = this.currLine;
                        try {
                            this.currLine = this.br.readLine();

                        } catch (IOException e) {
                            this.currLine = null;
                            throw new IllegalStateException(e);
                        }
                        return ans;

                    } else {
                        throw new NoSuchElementException();
                    }
                }

                @Override
                public void close() {
                    try {
                        this.currLine = null;
                        this.br.close();

                    } catch (IOException e) {
                        throw new IllegalStateException(e);
                    }
                }

                @Override
                public String getPath() {
                    return path;
                }
            };

        } catch (EOFException ex) {
            return new EmptyFileIterator();
        }
    }

    /**
     * Creates a factory to generate one or more readers for a (typically large)
     * file where each reader reads only part of the file.
     *
     * @param path       path to the file we want to read
     * @param numReaders number of readers we want to apply to read whole file
     * @param chunkSize
     * @param startLine
     * @see FilePartReaderFactory
     */
    public synchronized FilePartReaderFactory filePartReaderFactory(String path, int numReaders, Integer chunkSize,
            Integer startLine) {
        return new FilePartReaderFactory(new File(path), numReaders, chunkSize, startLine);
    }

    /**
     * Scans recursively a directory and creates numChunks iterators over these
     * files.
     *
     * @param pathList  list of directories to start search in
     * @param numChunks A number of chunks to be produced
     * @param filter    a regular expression to specify accepted files
     * @return
     */
    public DirectoryReader directoryReader(String[] pathList, int numChunks, String filter) {
        return new DirectoryReader(pathList, numChunks, filter);
    }

    /**
     * @param pathList
     * @param numChunks
     * @param filter
     * @return
     */
    public FilePairGenerator filePairGenerator(String[] pathList, int numChunks, String filter) {
        return new FilePairGenerator(pathList, numChunks, filter);
    }

    /**
     * @see TwoGroupFilePairGenerator
     */
    public TwoGroupFilePairGenerator twoGroupFilePairGenerator(String[] pathList1, String[] pathList2,
            int numChunks, String filter) {
        return new TwoGroupFilePairGenerator(pathList1, pathList2, numChunks, filter);
    }

    /**
     * Saves a string to a file.
     *
     * @param path
     * @param s    string to be saved
     * @return true on success else false
     */
    public boolean saveText(String path, String s) {
        FileWriter writer;
        BufferedWriter bWriter = null;

        try {
            writer = new FileWriter(new File(path));
            bWriter = new BufferedWriter(writer);
            bWriter.write(s);

        } catch (IOException ex) {
            LOG.error(ex.getMessage());

        } finally {
            if (bWriter != null) {
                try {
                    bWriter.close();
                } catch (IOException ex2) {
                    LOG.error(ex2.getMessage());
                }
            }
        }
        return false;
    }

    /**
     * Read a whole utf-8 text file at once.
     *
     * @param path
     * @return
     */
    public String readText(String path) {
        String ans = null;

        try {
            ans = FileUtils.readFileToString(new File(path), StandardCharsets.UTF_8);

        } catch (IOException | UnsupportedCharsetException ex) {
            LOG.error(ex.getMessage());
        }
        return ans;
    }

    /**
     * Creates a buffered file writer.
     */
    public BufferedWriter createTextFileWriter(String path) throws IOException {
        return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path, false), "UTF-8"));
    }

    /**
     * @param path
     * @throws IOException
     */
    public void cleanDirectory(String path) throws IOException {
        FileUtils.cleanDirectory(new File(path));
    }

    public void moveFile(String srcPath, String dstPath) throws IOException {
        File src = new File(srcPath);
        File dst = new File(dstPath);

        if (src.isFile() && dst.getParentFile().isDirectory() && !dst.exists()) {
            FileUtils.moveFile(src, dst);

        } else if (src.isFile() && dst.isDirectory()) {
            FileUtils.moveFileToDirectory(src, dst, false);

        } else {
            throw new IllegalArgumentException(
                    "srcPath must be a file, dstPath must be either a (non-existing) file or a directory");
        }
    }

    public void copyFile(String srcPath, String dstPath) throws IOException {
        File src = new File(srcPath);
        File dst = new File(dstPath);

        if (src.isFile() && dst.getParentFile().isDirectory() && !dst.exists()) {
            FileUtils.copyFile(src, dst);

        } else if (src.isFile() && dst.isDirectory()) {
            FileUtils.copyFileToDirectory(src, dst);

        } else {
            throw new IllegalArgumentException(
                    "srcPath must be a file, dstPath must be either a (non-existing) file or a directory");
        }
    }

    public long getLastModified(String path) {
        return new File(path).lastModified();
    }

    public long getSize(String path) {
        return FileUtils.sizeOf(new File(path));
    }

    public boolean exists(String path) {
        return new File(path).exists();
    }
}