org.apache.jena.atlas.io.IO.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.jena.atlas.io.IO.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.jena.atlas.io;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
import org.apache.commons.compress.compressors.snappy.SnappyCompressorInputStream;
import org.apache.commons.io.FilenameUtils;
import org.apache.jena.atlas.RuntimeIOException;
import org.apache.jena.atlas.lib.IRILib;

public class IO {
    public static final int EOF = -1;
    public static final int UNSET = -2;

    // Buffer size.  Larger than Java's default.
    private static final int BUFFER_SIZE = 128 * 1024;

    private static Charset utf8 = StandardCharsets.UTF_8;
    private static Charset ascii = StandardCharsets.US_ASCII;

    /** Open an input stream to a file. 
     * If the filename is null or "-", return System.in
     * If the filename ends in .gz, wrap in  GZIPInputStream  
     */
    static public InputStream openFile(String filename) {
        try {
            return openFileEx(filename);
        } catch (IOException ex) {
            IO.exception(ex);
            return null;
        }
    }

    /**
     * Open an input stream to a file and buffer it. If the filename is null or "-",
     * return System.in If the filename ends in .gz, wrap in GZIPInputStream.
     * If using this {@code InputStream} with an {@code InputStreamReader}
     * (e.g. to get UTF-8), there is no need to buffer the {@code InputStream}.
     * Instead, buffer the {@code Reader}. 
     */
    static public InputStream openFileBuffered(String filename) {
        try {
            InputStream in = openFileEx(filename);
            return new BufferedInputStream(in, BUFFER_SIZE);
        } catch (IOException ex) {
            IO.exception(ex);
            return null;
        }
    }

    /** Open an input stream to a file; do not mask IOExceptions. 
     * If the filename is null or "-", return System.in
     * If the filename ends in .gz, wrap in GZIPInputStream  
     * @param filename
     * @throws FileNotFoundException 
     * @throws IOException
     */
    static public InputStream openFileEx(String filename) throws IOException, FileNotFoundException {
        if (filename == null || filename.equals("-"))
            return System.in;
        if (filename.startsWith("file:")) {
            filename = filename.substring("file:".length());
            filename = IRILib.decode(filename);
        }
        InputStream in = new FileInputStream(filename);
        String ext = FilenameUtils.getExtension(filename);
        switch (ext) {
        case "":
            return in;
        case "gz":
            return new GZIPInputStream(in);
        case "bz2":
            return new BZip2CompressorInputStream(in);
        case "sz":
            return new SnappyCompressorInputStream(in);
        }
        return in;
    }

    private static String[] extensions = { "gz", "bz2", "sz" };

    /** The filename without any compression extension, or the original filename.
     *  It tests for compression types handled by {@link #openFileEx}.
     */
    static public String filenameNoCompression(String filename) {
        if (FilenameUtils.isExtension(filename, extensions)) {
            return FilenameUtils.removeExtension(filename);
        }
        return filename;
    }

    /** Open a UTF8 Reader for a file. 
     * If the filename is null or "-", use System.in
     * If the filename ends in .gz, use GZIPInputStream  
     */
    static public Reader openFileUTF8(String filename) {
        return openFileReader(filename, utf8);
    }

    /** Open an ASCII Reader for a file. 
     * If the filename is null or "-", use System.in
     * If the filename ends in .gz, use GZIPInputStream  
     */
    static public Reader openFileASCII(String filename) {
        return openFileReader(filename, ascii);
    }

    private static Reader openFileReader(String filename, Charset charset) {
        InputStream in = openFile(filename);
        return new InputStreamReader(in, charset);
    }

    /** Create an unbuffered reader that uses UTF-8 encoding */
    static public Reader asUTF8(InputStream in) {
        return new InputStreamReader(in, utf8.newDecoder());
    }

    /** Create a unbuffered reader that uses ASCII encoding */
    static public Reader asASCII(InputStream in) {
        return new InputStreamReader(in, ascii.newDecoder());
    }

    /** Create an buffered reader that uses UTF-8 encoding */
    static public BufferedReader asBufferedUTF8(InputStream in) {
        return new BufferedReader(asUTF8(in));
    }

    /** Create a writer that uses UTF-8 encoding */
    static public Writer asUTF8(OutputStream out) {
        return new OutputStreamWriter(out, utf8.newEncoder());
    }

    /** Create a writer that uses ASCII encoding */
    static public Writer asASCII(OutputStream out) {
        return new OutputStreamWriter(out, ascii.newEncoder());
    }

    /** Create a writer that uses UTF-8 encoding and is buffered. */
    static public Writer asBufferedUTF8(OutputStream out) {
        Writer w = new OutputStreamWriter(out, utf8.newEncoder());
        return new BufferingWriter(w);
    }

    /** Open a file for output - may include adding gzip processing. */
    static public OutputStream openOutputFile(String filename) {
        try {
            return openOutputFileEx(filename);
        } catch (IOException ex) {
            IO.exception(ex);
            return null;
        }
    }

    /** Open an input stream to a file; do not mask IOExceptions. 
     * If the filename ends in .gz, wrap in GZIPOutputStream  
     * @param filename
     * @throws FileNotFoundException If the output can't be opened.
     * @throws IOException for bad gzip encoded data
     */
    static public OutputStream openOutputFileEx(String filename) throws FileNotFoundException, IOException {
        if (filename == null || filename.equals("-"))
            return System.out;
        if (filename.startsWith("file:")) {
            filename = filename.substring("file:".length());
            filename = IRILib.decode(filename);
        }
        OutputStream out = new FileOutputStream(filename);
        String ext = FilenameUtils.getExtension(filename);
        switch (ext) {
        case "":
            return out;
        case "gz":
            return new GZIPOutputStream(out);
        case "bz2":
            return new BZip2CompressorOutputStream(out);
        case "sz":
            throw new UnsupportedOperationException("Snappy output");
        }
        return out;
    }

    /** Wrap in a general writer interface */
    static public AWriter wrap(Writer w) {
        return Writer2.wrap(w);
    }

    /** Wrap in a general writer interface */
    static public AWriter wrapUTF8(OutputStream out) {
        return wrap(asUTF8(out));
    }

    /** Wrap in a general writer interface */
    static public AWriter wrapASCII(OutputStream out) {
        return wrap(asASCII(out));
    }

    /** Create a print writer that uses UTF-8 encoding */
    static public PrintWriter asPrintWriterUTF8(OutputStream out) {
        return new PrintWriter(asUTF8(out));
    }

    public static void close(org.apache.jena.atlas.lib.Closeable resource) {
        resource.close();
    }

    public static void closeSilent(org.apache.jena.atlas.lib.Closeable resource) {
        try {
            resource.close();
        } catch (Exception ex) {
        }
    }

    public static void close(java.io.Closeable resource) {
        if (resource == null)
            return;
        try {
            resource.close();
        } catch (IOException ex) {
            exception(ex);
        }
    }

    public static void closeSilent(java.io.Closeable resource) {
        if (resource == null)
            return;
        try {
            resource.close();
        } catch (IOException ex) {
        }
    }

    public static void close(AWriter resource) {
        if (resource == null)
            return;
        resource.close();
    }

    public static void closeSilent(AWriter resource) {
        if (resource == null)
            return;
        try {
            resource.close();
        } catch (Exception ex) {
        }
    }

    public static void close(IndentedWriter resource) {
        if (resource == null)
            return;
        resource.close();
    }

    public static void closeSilent(IndentedWriter resource) {
        if (resource == null)
            return;
        try {
            resource.close();
        } catch (Exception ex) {
        }
    }

    /** Throw a RuntimeIOException - this function is guaranteed not to return normally */
    public static void exception(String message) {
        throw new RuntimeIOException(message);
    }

    /** Throw a RuntimeIOException - this function is guaranteed not to return normally */
    public static void exception(IOException ex) {
        throw new RuntimeIOException(ex);
    }

    /** Throw a RuntimeIOException - this function is guaranteed not to return normally */
    public static void exception(String msg, IOException ex) {
        throw new RuntimeIOException(msg, ex);
    }

    public static void flush(OutputStream out) {
        if (out == null)
            return;
        try {
            out.flush();
        } catch (IOException ex) {
            exception(ex);
        }
    }

    public static void flush(Writer out) {
        if (out == null)
            return;
        try {
            out.flush();
        } catch (IOException ex) {
            exception(ex);
        }
    }

    public static void flush(AWriter out) {
        if (out == null)
            return;
        out.flush();
    }

    public static byte[] readWholeFile(InputStream in) {
        final int WHOLE_FILE_BUFFER_SIZE = 32 * 1024;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream(WHOLE_FILE_BUFFER_SIZE)) {
            byte buff[] = new byte[WHOLE_FILE_BUFFER_SIZE];
            while (true) {
                int l = in.read(buff);
                if (l <= 0)
                    break;
                out.write(buff, 0, l);
            }
            return out.toByteArray();
        } catch (IOException ex) {
            exception(ex);
            return null;
        }
    }

    /** Read a whole file as UTF-8
     * @param filename
     * @return String
     * @throws IOException
     */

    public static String readWholeFileAsUTF8(String filename) throws IOException {
        try (InputStream in = new FileInputStream(filename)) {
            return readWholeFileAsUTF8(in);
        }
    }

    /** Read a whole stream as UTF-8
     * 
     * @param in    InputStream to be read
     * @return      String
     * @throws IOException
     */
    public static String readWholeFileAsUTF8(InputStream in) throws IOException {
        // Don't buffer - we're going to read in large chunks anyway
        try (Reader r = asUTF8(in)) {
            return readWholeFileAsUTF8(r);
        }
    }

    /** Read a whole file as UTF-8
     * 
     * @param r
     * @return String The whole file
     * @throws IOException
     */

    // Private worker as we are trying to force UTF-8. 
    private static String readWholeFileAsUTF8(Reader r) throws IOException {
        final int WHOLE_FILE_BUFFER_SIZE = 32 * 1024;
        try (StringWriter sw = new StringWriter(WHOLE_FILE_BUFFER_SIZE)) {
            char buff[] = new char[WHOLE_FILE_BUFFER_SIZE];
            for (;;) {
                int l = r.read(buff);
                if (l < 0)
                    break;
                sw.write(buff, 0, l);
            }
            return sw.toString();
        }
    }

    public static String uniqueFilename(String directory, String base, String ext) {
        File d = new File(directory);
        if (!d.exists())
            throw new IllegalArgumentException("Not found: " + directory);
        try {
            String fn0 = d.getCanonicalPath() + File.separator + base;
            String fn = fn0;
            int x = 1;
            while (true) {
                if (ext != null)
                    fn = fn + "." + ext;
                File f = new File(fn);
                if (!f.exists())
                    return fn;
                fn = fn0 + "-" + (x++);
            }
        } catch (IOException e) {
            IO.exception(e);
            return null;
        }
    }

    /** Delete everything from a {@code Path} start point, including the path itself.
     * This function works on files or directories.
     * This function does not follow symbolic links.
     */
    public static void deleteAll(Path start) {
        // Walks down the tree and delete directories on the way backup.
        try {
            Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.delete(file);
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
                    if (e == null) {
                        Files.delete(dir);
                        return FileVisitResult.CONTINUE;
                    } else {
                        throw e;
                    }
                }
            });
        } catch (IOException ex) {
            IO.exception(ex);
            return;
        }
    }
}