/** * Copyright (c) 2011-2013 Robert Maupin * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. */ package org.csdgn.maru; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Serializable; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; /** * A number of useful static methods to make working with IO much easier. * * Many of the methods purposely ignore exceptions and return a sentinel value on failure. * * @author Robert Maupin */ public class Files { private static final int IO_BUFFER_SIZE = 16384; /** * Get an every byte from an input stream and put it into a byte array. * * @param stream * Input stream to read from * @return bytes retrieved from stream * @throws IOException * if an error occurs */ public static byte[] get(InputStream stream) throws IOException { if (stream != null) { /* * This is the fastest method I know for reading from an * indeterminate stream. So fast in fact, that it pars fairly well * with FileChannel stuff in test cases. * * Small and simple enough the JIT can grab hold and optimize it, * but with a large enough buffer to not make reading slow. */ final BufferedInputStream input = new BufferedInputStream(stream); final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); /* magic */ final byte[] reader = new byte[IO_BUFFER_SIZE]; int r = 0; while ((r = input.read(reader, 0, IO_BUFFER_SIZE)) != -1) { buffer.write(reader, 0, r); } buffer.flush(); return buffer.toByteArray(); } return null; } /** * Get an every byte from an input stream and put it into a byte array. * * @param stream * Input stream to read from * @return bytes retrieved from stream * @throws IOException * if an error occurs */ public static final String get(Reader reader) throws IOException { if (reader != null) { /* * This is the fastest method I know for reading from an * indeterminate reader. So fast in fact, that it pars fairly well * with FileChannel stuff in test cases. * * Small and simple enough the JIT can grab hold and optimize it, * but with a large enough buffer to not make reading slow. */ final BufferedReader input = new BufferedReader(reader); final StringBuilder buffer = new StringBuilder(); final char[] read = new char[IO_BUFFER_SIZE]; int r = 0; while ((r = input.read(read, 0, IO_BUFFER_SIZE)) != -1) { buffer.append(read, 0, r); } return buffer.toString(); } return null; } /** * Get an every byte from an input stream and put it into a byte array. Then * it also closes the stream after it is done. * * @param stream * Input stream to read from * @return bytes retrieved from stream * @throws IOException * if an error occurs */ public static byte[] getAndClose(InputStream stream) throws IOException { if (stream != null) { try { /* * This is the fastest method I know for reading from an * indeterminate stream. So fast in fact, that it pars fairly * well with FileChannel stuff in test cases. * * Small and simple enough the JIT can grab hold and optimize * it, but with a large enough buffer to not make reading slow. */ final BufferedInputStream input = new BufferedInputStream(stream); final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); /* magic */ final byte[] reader = new byte[IO_BUFFER_SIZE]; int r = 0; while ((r = input.read(reader, 0, IO_BUFFER_SIZE)) != -1) { buffer.write(reader, 0, r); } buffer.flush(); return buffer.toByteArray(); } finally { stream.close(); } } return null; } /** * Get an every character from a reader and put it into a string. Then * it also closes the reader after it is done. * * @param reader * Reader to read from * @return String retrieved from stream * @throws IOException * if an error occurs */ public static final String getAndClose(Reader reader) throws IOException { if (reader != null) { try { /* * This is the fastest method I know for reading from an * indeterminate reader. So fast in fact, that it pars fairly * well with FileChannel stuff in test cases. * * Small and simple enough the JIT can grab hold and optimize * it, but with a large enough buffer to not make reading slow. */ final BufferedReader input = new BufferedReader(reader); final StringBuilder buffer = new StringBuilder(); final char[] read = new char[IO_BUFFER_SIZE]; int r = 0; while ((r = input.read(read, 0, IO_BUFFER_SIZE)) != -1) { buffer.append(read, 0, r); } return buffer.toString(); } finally { reader.close(); } } return null; } /** * Get an every character from a reader and put it into a string. Then * it also closes the reader after it is done. * * @param reader * Reader to read from * @return String retrieved from stream * @throws IOException * if an error occurs */ public static final String[] getLinesAndClose(Reader reader) throws IOException { if (reader != null) { try { final BufferedReader input = new BufferedReader(reader); ArrayList<String> lines = new ArrayList<String>(); while (true) { String line = input.readLine(); if(line == null) break; lines.add(line); } return lines.toArray(new String[lines.size()]); } finally { reader.close(); } } return null; } /** * Gets the contents of the given file. * * @param file * The file. * @return the contents of the file, or <code>null</code> on failure */ public static byte[] getFileContents(File file) { try { return getAndClose(new FileInputStream(file)); } catch (IOException e) { } return null; } /** * Gets the contents of the given file. * * @param filename * The file's filename. * @return the contents of the file, or <code>null</code> on failure */ public static byte[] getFileContents(String filename) { try { return getAndClose(new FileInputStream(filename)); } catch (IOException e) { } return null; } /** * Reads a serialized object from the given file. * * @param file * The file. * @return Object read, or null on failure. */ public static Object getFileObject(File file) { ObjectInputStream ois = null; try { ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file))); return ois.readObject(); } catch (Exception e) { } finally { if (ois != null) { try { ois.close(); } catch (IOException e) { } } } return null; } /** * Reads a serialized object from the given file. * * @param filename * The file. * @return Object read, or null on failure. */ public static Object getFileObject(String filename) { ObjectInputStream ois = null; try { ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(filename))); return ois.readObject(); } catch (Exception e) { } finally { if (ois != null) { try { ois.close(); } catch (IOException e) { } } } return null; } /** * Gets the contents of the given file. * * @param file * The file. * @return the contents of the file, or <code>null</code> on failure */ public static String getFileStringContents(File file) { try { return getAndClose(new FileReader(file)); } catch (IOException e) { } return null; } /** * Gets the contents of the given file. * * @param file * The file. * @param cs * The charset to decode the file with. * @return the contents of the file, or <code>null</code> on failure */ public static String getFileStringContents(File file, Charset cs) { try { return getAndClose(new InputStreamReader(new FileInputStream(file), cs)); } catch (IOException e) { } return null; } /** * Gets the contents of the given file. * * @param filename * The file's filename. * @return the contents of the file, or <code>null</code> on failure */ public static String getFileStringContents(String filename) { try { return getAndClose(new FileReader(filename)); } catch (IOException e) { } return null; } /** * Gets the contents of the given file. * * @param filename * The file's filename. * @param cs * The charset to decode the file with. * @return the contents of the file, or <code>null</code> on failure */ public static String getFileStringContents(String filename, Charset cs) { try { return getAndClose(new InputStreamReader(new FileInputStream(filename), cs)); } catch (IOException e) { } return null; } /** * Gets the lines of the given file. Splits on \n, \r, and \r\n * * @param file * The file. * @return the contents of the file, or <code>null</code> on failure */ public static String[] getFileLines(File file) { try { return getLinesAndClose(new FileReader(file)); } catch (IOException e) { } return null; } /** * Gets the lines of the given file. Splits on \n, \r\n, and \r. * * @param file * The file. * @param cs * The charset to decode the file with. * @return the contents of the file, or <code>null</code> on failure */ public static String[] getFileLines(File file, Charset cs) { try { return getLinesAndClose(new InputStreamReader(new FileInputStream(file), cs)); } catch (IOException e) { } return null; } /** * Gets the lines of the given file. Splits on \n, \r\n, and \r. * * @param filename * The file's filename. * @return the contents of the file, or <code>null</code> on failure */ public static String[] getFileLines(String filename) { try { return getLinesAndClose(new FileReader(filename)); } catch (IOException e) { } return null; } /** * Gets the lines of the given file. Splits on \n, \r\n, and \r. * * @param filename * The file's filename. * @param cs * The charset to decode the file with. * @return the contents of the file, or <code>null</code> on failure */ public static String[] getFileLines(String filename, Charset cs) { try { return getLinesAndClose(new InputStreamReader(new FileInputStream(filename), cs)); } catch (IOException e) { } return null; } /** * Writes to the output as it gets data from the input. * * @param istream * Input stream to read from * @param ostream * Output stream to write to * @throws IOException * if an error occurs */ public static void pipe(InputStream istream, OutputStream ostream) throws IOException { if (ostream != null && istream != null) { /* * This is the fastest method I know for reading from an * indeterminate stream. So fast in fact, that it pars fairly well * with FileChannel stuff in test cases. * * Small and simple enough the JIT can grab hold and optimize it, * but with a large enough buffer to not make reading slow. */ final BufferedInputStream input = new BufferedInputStream(istream); final BufferedOutputStream output = new BufferedOutputStream(ostream); // final FileOutputStream buffer = new FileOutputStream(file); final byte[] reader = new byte[IO_BUFFER_SIZE]; int r = 0; while ((r = input.read(reader, 0, IO_BUFFER_SIZE)) != -1) { output.write(reader, 0, r); } output.flush(); } } /** * Writes to the output as it gets data from the input. Finally it closes * both. * * @param istream * Input stream to read from * @param ostream * Output stream to write to * @throws IOException * if an error occurs */ public static void pipeAndClose(InputStream istream, OutputStream ostream) throws IOException { if (ostream != null && istream != null) { try { /* * This is the fastest method I know for reading from an * indeterminate stream. So fast in fact, that it pars fairly * well with FileChannel stuff in test cases. * * Small and simple enough the JIT can grab hold and optimize * it, but with a large enough buffer to not make reading slow. */ final BufferedInputStream input = new BufferedInputStream(istream); final BufferedOutputStream output = new BufferedOutputStream(ostream); final byte[] reader = new byte[IO_BUFFER_SIZE]; int r = 0; while ((r = input.read(reader, 0, IO_BUFFER_SIZE)) != -1) { output.write(reader, 0, r); } output.flush(); input.close(); output.close(); } finally { istream.close(); ostream.close(); } } } /** * Sets the contents of the given file. * * @param file * The file. * @param contents * The contents to store. * @return <code>true</code> on success, <code>false</code> otherwise. */ public static boolean setFileContents(File file, byte[] contents) { OutputStream fos = null; try { fos = new BufferedOutputStream(new FileOutputStream(file)); fos.write(contents); fos.flush(); return true; } catch (IOException e) { } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { } } } return false; } /** * Sets the contents of the given file. * * @param file * The file. * @param contents * The contents to store. * @return <code>true</code> on success, <code>false</code> otherwise. */ public static boolean setFileContents(File file, String contents) { FileWriter fw = null; try { fw = new FileWriter(file); fw.write(contents); return true; } catch (IOException e) { } finally { if (fw != null) { try { fw.close(); } catch (IOException e) { } } } return false; } /** * Sets the contents of the given file. * * @param filename * The file's filename. * @param contents * The contents to store. * @return <code>true</code> on success, <code>false</code> otherwise. */ public static boolean setFileContents(String filename, byte[] contents) { OutputStream fos = null; try { fos = new BufferedOutputStream(new FileOutputStream(filename)); fos.write(contents); fos.flush(); return true; } catch (IOException e) { } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { } } } return false; } /** * Sets the contents of the given file. * * @param filename * The file's filename. * @param contents * The contents to store. * @return <code>true</code> on success, <code>false</code> otherwise. */ public static boolean setFileContents(String filename, String contents) { FileWriter fw = null; try { fw = new FileWriter(filename); fw.write(contents); return true; } catch (IOException e) { } finally { if (fw != null) { try { fw.close(); } catch (IOException e) { } } } return false; } /** * Sets the object to the given file. * * @param file * The file. * @param obj * The object to store. * @return <code>true</code> on success, <code>false</code> otherwise. */ public static boolean setFileObject(File file, Serializable obj) { ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); oos.writeObject(obj); oos.flush(); return true; } catch (IOException e) { } finally { if (oos != null) { try { oos.close(); } catch (IOException e) { } } } return false; } /** * Sets the object to the given file. * * @param filename * The file. * @param obj * The object to store. * @return <code>true</code> on success, <code>false</code> otherwise. */ public static boolean setFileObject(String filename, Serializable obj) { ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(filename))); oos.writeObject(obj); oos.flush(); return true; } catch (IOException e) { } finally { if (oos != null) { try { oos.close(); } catch (IOException e) { } } } return false; } public static String getPathString(File file) { return file.getParent(); } public static byte[] gzip(byte[] data) { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); try { GZIPOutputStream gzip = new GZIPOutputStream(buffer); gzip.write(data); gzip.close(); } catch(Exception e) { e.printStackTrace(); } return buffer.toByteArray(); } public static byte[] ungzip(byte[] data) { try { GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(data)); return getAndClose(gzip); } catch(Exception e) { e.printStackTrace(); } return null; } private Files() { } }