/******************************************************************************* * OSUG-DOI project ( http://doi.osug.fr ) - Copyright (C) CNRS. ******************************************************************************/ package fr.osug.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * File utility methods : Several utility methods : finds a file in the class path (jar), open files * for read or write operation and close file */ public final class FileUtils { /** class logger */ private static Logger log = LoggerFactory.getLogger(FileUtils.class.getName()); /** default read buffer capacity : DEFAULT_READ_BUFFER_SIZE = 8K */ private static final int DEFAULT_READ_BUFFER_SIZE = 8 * 1024; /** default write buffer capacity : DEFAULT_WRITE_BUFFER_SIZE = 8K */ private static final int DEFAULT_WRITE_BUFFER_SIZE = 8 * 1024; /** File encoding use UTF-8 */ public static final String FILE_ENCODING = "UTF-8"; /** * Forbidden FileUtils constructor */ private FileUtils() { /* no-op */ } public static File createDirectories(final String path) throws IOException { final File dir = new File(path).getCanonicalFile(); if (!dir.exists()) { dir.mkdirs(); } return dir; } /** * Find a file in the current classloader (application class Loader) * * @param fileName file name only no path included * @return URL to the file or null */ public static URL getResource(final String fileName) { // Find properties in the classpath final URL url = FileUtils.class.getClassLoader().getResource(fileName); if (url == null) { throw new RuntimeException("Unable to find the file in classpath : " + fileName); } if (log.isInfoEnabled()) { log.info("FileUtils.getSystemFileInputStream : URL : " + url); } return url; } /** * Find a file in the current classloader (application class Loader) * * @param fileName file name only no path included * @return InputStream or RuntimeException if not found * @throws RuntimeException if not found */ public static InputStream getSystemFileInputStream(final String fileName) { final URL url = getResource(fileName); try { return url.openStream(); } catch (final IOException ioe) { throw new RuntimeException("Failure when loading file in classpath : " + fileName, ioe); } } /** * Close an inputStream * * @param in inputStream to close */ public static void closeStream(final InputStream in) { if (in != null) { try { in.close(); } catch (final IOException ioe) { log.error("FileUtils.closeStream : io close failure : ", ioe); } } } /** * Close an outputStream * * @param out outputStream to close */ public static void closeStream(final OutputStream out) { if (out != null) { try { out.close(); } catch (final IOException ioe) { log.error("FileUtils.closeStream : io close failure : ", ioe); } } } /** * Returns an exisiting File for the given path * * @param file file path * @return File or null */ private static File getExistingFile(final File file) { if (file != null) { if (file.exists()) { return file; } } return null; } /** * Returns an exisiting File for the given path * * @param path file path * @return File or null */ private static File getExistingFile(final String path) { if (path != null && !path.isEmpty()) { return getExistingFile(new File(path)); } return null; } /** * Returns an existing directory for the given path * * @param path directory path * @return directory or null */ public static File getDirectory(final String path) { final File dir = getExistingFile(path); if (dir != null && dir.isDirectory()) { return dir; } return null; } /** * Returns an existing directory for the given path * * @param path directory path * @return directory or null */ public static File getRequiredDirectory(final String path) throws IOException { final File dir = getDirectory(path); if (dir != null) { return dir; } throw new FileNotFoundException("Invalid directory '" + ((dir == null) ? null : dir.getAbsolutePath()) + "' !"); } /** * Returns an exisiting File for the given path * * @param path file path * @return File or null */ public static File getFile(final String path) { final File file = getExistingFile(path); if (file != null && file.isFile()) { return file; } return null; } /** * Returns an exisiting File for the given path * * @param file file path * @return File or null */ public static File getFile(final File file) { final File eFile = getExistingFile(file); if (eFile != null) { return file; } return null; } /** * Returns an existing File for the given path * * @param file file path * @return File or null */ public static File getRequiredFile(final File file) throws IOException { final File eFile = getFile(file); if (eFile != null) { return eFile; } throw new FileNotFoundException("Invalid file '" + ((file == null) ? null : file.getAbsolutePath()) + "' !"); } /** * Returns an existing File for the given path * * @param path file path * @return File or null */ public static File getRequiredFile(final String path) throws IOException { final File file = getFile(path); if (file != null) { return file; } throw new FileNotFoundException("Invalid file '" + ((file == null) ? null : file.getAbsolutePath()) + "' !"); } // writers : /** * Returns a Writer for the given file path and use the default writer buffer capacity * * @param absoluteFilePath absolute file path * @return Writer (buffered) or null */ public static Writer openFile(final String absoluteFilePath) { return openFile(absoluteFilePath, DEFAULT_WRITE_BUFFER_SIZE); } /** * Returns a Writer for the given file path and use the given buffer capacity * * @param absoluteFilePath absolute file path * @param bufferSize write buffer capacity * @return Writer (buffered) or null */ public static Writer openFile(final String absoluteFilePath, final int bufferSize) { if (absoluteFilePath != null && !absoluteFilePath.isEmpty()) { return openFile(new File(absoluteFilePath), bufferSize); } return null; } /** * Returns a Writer for the given file and use the default writer buffer capacity * * @param file file to write * @return Writer (buffered) or null */ public static Writer openFile(final File file) { return openFile(file, DEFAULT_WRITE_BUFFER_SIZE); } /** * Returns a Writer for the given file and use the given buffer capacity * * @param file file to write * @param bufferSize write buffer capacity * @return Writer (buffered) or null */ public static Writer openFile(final File file, final int bufferSize) { try { return new BufferedWriter(new FileWriter(file), bufferSize); } catch (final IOException ioe) { log.error("FileUtils.openFile : io failure : ", ioe); } return null; } /** * Returns a Reader for the given file * * @param file file to read * @return Reader or null */ public static Reader reader(final File file) throws IOException { return new InputStreamReader(new FileInputStream(file), FILE_ENCODING); } /** * Close the given writer * * @param w writer to close * @return null */ public static Writer closeFile(final Writer w) { if (w != null) { try { w.close(); } catch (final IOException ioe) { log.error("FileUtils.closeFile : io close failure : ", ioe); } } return null; } /** * Get the file name part without extension * * @param file file as File * @return the file name part without extension or null */ public static String getFileNameWithoutExtension(final File file) { if (file != null) { return getFileNameWithoutExtension(file.getName()); } return null; } /** * Get the file name part without extension * * @param fileName file name as String * @return the file name part without extension or null */ public static String getFileNameWithoutExtension(final String fileName) { if (fileName != null) { final int pos = fileName.lastIndexOf('.'); if (pos == -1) { return fileName; } if (pos > 0) { return fileName.substring(0, pos); } } return null; } /** * Read a text file from the given file * * @param file local file * @return text file content * * @throws IOException if an I/O exception occurred */ public static String readFile(final File file) throws IOException { return readStream(new FileInputStream(file), (int) file.length()); } /** * Read a text file from the given input stream into a string * * @param inputStream stream to load * @return text file content * * @throws IOException if an I/O exception occurred */ public static String readStream(final InputStream inputStream) throws IOException { return readStream(inputStream, DEFAULT_READ_BUFFER_SIZE); } /** * Read a text file from the given input stream into a string * * @param inputStream stream to load * @param bufferCapacity initial buffer capacity (chars) * @return text file content * * @throws IOException if an I/O exception occurred */ public static String readStream(final InputStream inputStream, final int bufferCapacity) throws IOException { String result = null; BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(inputStream, FILE_ENCODING)); // Use one string buffer with the best guessed initial capacity: final StringBuilder sb = new StringBuilder(bufferCapacity); // Use a char buffer to consume reader using DEFAULT_BUFFER_CAPACITY: final char[] cbuf = new char[DEFAULT_READ_BUFFER_SIZE]; int len; while ((len = reader.read(cbuf)) > 0) { sb.append(cbuf, 0, len); } result = sb.toString(); } finally { closeFile(reader); } return result; } /** * Close the given reader * * @param r reader to close * @return null */ public static Reader closeFile(final Reader r) { if (r != null) { try { r.close(); } catch (final IOException ioe) { log.error("FileUtils.closeFile : io close failure : ", ioe); } } return null; } /** * Copy file * * @param src source file * @param dst destination file * @throws IOException if an I/O exception occurred * @throws FileNotFoundException if input file is not found */ public static void copy(final File src, final File dst) throws IOException, FileNotFoundException { final InputStream in = new BufferedInputStream(new FileInputStream(src), DEFAULT_READ_BUFFER_SIZE); saveStream(in, dst); } /** * Save the given input stream as file. * * @param in input stream to save as file * @param dst destination file * @throws IOException if an I/O exception occurred */ public static void saveStream(final InputStream in, final File dst) throws IOException { final OutputStream out = new BufferedOutputStream(new FileOutputStream(dst), DEFAULT_WRITE_BUFFER_SIZE); // Transfer bytes from in to out try { final byte[] buf = new byte[DEFAULT_READ_BUFFER_SIZE]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } } finally { closeStream(in); closeStream(out); } } public static long computeChecksum(final InputStream in) throws IOException { final ChecksumOutputStream cs = new ChecksumOutputStream(); final byte[] buf = new byte[DEFAULT_READ_BUFFER_SIZE]; int len; while ((len = in.read(buf)) > 0) { cs.write(buf, 0, len); } return cs.getChecksum(); // flush and close streams } public static String MD5(final InputStream in) throws IOException { try { final MessageDigest md = MessageDigest.getInstance("MD5"); final byte[] buf = new byte[DEFAULT_READ_BUFFER_SIZE]; int len; while ((len = in.read(buf)) > 0) { md.update(buf, 0, len); } final byte[] array = md.digest(); final StringBuilder sb = new StringBuilder(32); for (int i = 0; i < array.length; ++i) { final String num = Integer.toHexString(array[i] & 0xFF); // max 2 digits if (num.length() == 1) { sb.append('0'); } sb.append(num); } return sb.toString(); } catch (NoSuchAlgorithmException nsae) { log.error("Unsupported algorithm", nsae); } return null; } }