/* * IOHelper.java * * Copyright (c) 2004-2008 Gregory Kotsaftis * gregkotsaftis@yahoo.com * http://zeus-jscl.sourceforge.net/ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package edu.mbl.jif.io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; /** * IO helper methods. * <p> * @author Gregory Kotsaftis * @since 1.0 */ public final class IOHelper { /** * Buffer size. */ private static final int IO_BUF_SIZE = 1024 * 32; /** * Path separator for Windows OS. */ private static final String BACKSLASH = "\\"; /** * Path separator for Unix OS. */ private static final String SLASH = "/"; /** * Creates the complete directory structure for a complete * <b>FOLDER</b> pathname. * <p> * @param folder The folder pathname. * <p> * @return The folder pathname. * <p> * @throws IOException */ public static String createDirectoryTreeForFolder(String folder) throws IOException { if( folder==null ) { throw new IOException("The requested folder is null!"); } if( !folder.endsWith( BACKSLASH ) && !folder.endsWith( SLASH ) ) { folder += SLASH; } File f = new File( folder ); if( !f.exists() ) { boolean result = f.mkdirs(); // build all required directories! if( result==false ) { throw new IOException("Cannot create folder structure for: " + folder); } } else if( !f.isDirectory() ) { throw new IOException( "Invalid directory/Cannot create directory: " + folder); } else { /* the folder already exists */ } return( folder ); } /** * Creates the complete directory structure for a complete * <b>FILE</b> pathname. * <p> * @param file The file pathname. * <p> * @throws IOException */ public static void createDirectoryTreeForFile(String file) throws IOException { if( file==null ) { throw new IOException("null file requested!"); } String path = null; int sep1 = file.lastIndexOf( BACKSLASH ); int sep2 = file.lastIndexOf( SLASH ); if( sep1==-1 && sep2==-1 ) { path = file; } else if( sep1!=-1 ) { path = file.substring(0, sep1); } else if( sep2!=-1 ) { path = file.substring(0, sep2); } else { // impossible throw new IOException("Cannot create folder structure for: " + file); } createDirectoryTreeForFolder( path ); } /** * Determines if two filename paths refer to the same file. * <p> * @param pathname1 The first pathname. * @param pathname2 The second pathname. * <p> * @return <code>true</code> if two filename paths refer * to the same file. * <p> * @throws IOException * <p> * @see <a href="http://javaalmanac.com/egs/java.io/Canonical.html"> * http://javaalmanac.com/egs/java.io/Canonical.html</a> */ public static boolean isTheSameFile(String pathname1, String pathname2) throws IOException { File file1 = new File( pathname1 ); File file2 = new File( pathname2 ); // Normalize the paths file1 = file1.getCanonicalFile(); file2 = file2.getCanonicalFile(); return( file1.equals(file2) ); } /** * Determines if a file or directory exists. * <p> * @param pathname The file or directory pathname. * <p> * @return <code>true</code> if it exists. */ public static boolean fileOrDirectoryExists(String pathname) { File f = new File(pathname); return( f.exists() ); } /** * Determines if a file exists. * <p> * @param pathname The file to check. * <p> * @return <code>true</code> if it exists. */ public static boolean isFile(String pathname) { File f = new File( pathname ); return( f.isFile() ); } /** * Determines if a directory exists. * <p> * @param pathname The directory pathname. * <p> * @return <code>true</code> if it exists. */ public static boolean isDirectory(String pathname) { File f = new File( pathname ); return( f.isDirectory() ); } /** * Saves a string to a text file. * <p> * @param pathname The pathname to the file. * @param data The string to be saved. * @param append <code>true</code> if the string is to be appended * to the end of existing text. * <p> * @throws IOException */ public static void saveTxtFile(String pathname, String data, boolean append) throws IOException { saveTxtFile(new File(pathname), data, append); } /** * Saves a string to a text file. * <p> * @param f The file. * @param data The string to save. * @param append <code>true</code> if the string is to be appended * to the end of existing text. * <p> * @throws IOException */ public static void saveTxtFile(File f, String data, boolean append) throws IOException { BufferedWriter out = null; try { out = new BufferedWriter( new FileWriter(f, append) ); out.write( data ); } catch(IOException e) { throw( e ); } finally { if( out!=null ) { try { out.close(); } catch(IOException ex) { //throw( ex ); ex.printStackTrace(); } } } } /** * Reads a text file into a string. * <p> * @param pathname The path to the text file. * <p> * @return The text in the file. * <p> * @throws IOException */ public static String readTxtFile(String pathname) throws IOException { return( readTxtFile( new File(pathname) ) ); } /** * Reads a text file into a string. * <p> * @param f The file. * <p> * @return The text in the file. * <p> * @throws IOException */ public static String readTxtFile(File f) throws IOException { BufferedReader in = null; StringBuilder strBuf = new StringBuilder(); try { in = new BufferedReader( new FileReader(f) ); String str = null; while( (str = in.readLine()) != null ) { strBuf.append( str ); strBuf.append( "\n" ); } } catch(IOException e) { throw( e ); } finally { if( in!=null ) { try { in.close(); } catch(IOException ex) { //throw( ex ); ex.printStackTrace(); } } } return( strBuf.toString() ); } /** * Deletes all files and subdirectories under <i>dir</i>. * Returns <code>true</code> if all deletions were successful. * If a deletion fails, the method stops attempting * to delete and returns <code>false</code>. * <p> * @param dir The directory to delete from. * <p> * @return <code>true</code> if all deletions were successful. */ public static boolean deleteDirectory(File dir) { if( dir.isDirectory() ) { String[] children = dir.list(); for(int i=0; i<children.length; i++) { boolean success = deleteDirectory( new File(dir, children[i]) ); if( !success ) { return( false ); } } } // This is a file or an empty directory, so just delete it return( dir.delete() ); } /** * Deletes all files and subdirectories under <i>dir</i>. * Returns <code>true</code> if all deletions were successful. * If a deletion fails, the method stops attempting * to delete and returns <code>false</code>. * <p> * @param pathname The path to the directory. * <p> * @return <code>true</code> if all deletions were successful. */ public static boolean deleteDirectory(String pathname) { return( deleteDirectory( new File(pathname) ) ); } /** * Deletes a file. * <p> * @param pathname The pathname to the file. * <p> * @return <code>true</code> if successful. */ public static boolean deleteFile(String pathname) { File f = new File( pathname ); return( f.delete() ); } /** * Copies a file to another location/file. * <p> * @param fromName The file to copy from. * @param toName The file to copy to. * @param overwrite <code>true</code> to overwrite if the file already * exists. * <p> * @return <code>true</code> if file copied or * <code>false</code> if not (possibly the file existed * and 'overwrite' was not set). * <p> * @throws IOException */ public static boolean copyFile(String fromName, String toName, boolean overwrite) throws IOException { if( fromName==null ) throw new IOException("source filename is null!"); if( toName==null ) throw new IOException("destination filename is null!"); File fromFile = new File(fromName); File toFile = new File(toName); return( copyFile(fromFile, toFile, overwrite) ); } /** * Copies a file to another location/file. * <p> * @param fromFile The file to copy from. * @param toFile The file to copy to. * @param overwrite <code>true</code> to overwrite if the file already * exists. * <p> * @return <code>true</code> if file copied or * <code>false</code> if not (possibly the file existed * and 'overwrite' was not set). * <p> * @throws IOException */ public static boolean copyFile(File fromFile, File toFile, boolean overwrite) throws IOException { if( fromFile==null ) throw new IOException("source file is null!"); if( toFile==null ) throw new IOException("destination file is null!"); // make sure that source file exists if( !fromFile.exists() ) throw new IOException("no such source file: " + fromFile.getAbsoluteFile()); if( !fromFile.isFile() ) throw new IOException("can't copy directory: " + fromFile.getAbsoluteFile()); if( !fromFile.canRead() ) throw new IOException("source file is unreadable: " + fromFile.getAbsoluteFile()); if( toFile.isDirectory() ) toFile = new File(toFile, fromFile.getName()); if( toFile.exists() ) { if( !toFile.canWrite() ) throw new IOException("destination file is unwriteable: " + toFile.getAbsoluteFile()); // check if we should overwrite it if( !overwrite ) { return( false ); } } else { // if the file dosn't exist, check if the directory exists and is // writeable. If getParent() returns null, then the directory is the // current dir. so look up the user.dir system property to find out // what that is. String parent = toFile.getParent(); // the destination dir if( parent==null ) // if none use the current dir parent = System.getProperty("user.dir"); File dir = new File( parent ); // convert it to a file if( !dir.exists() ) throw new IOException("destination directory doesn't exist: " + parent); if( dir.isFile() ) throw new IOException("destination is not a directory: " + parent); if( !dir.canWrite() ) throw new IOException("destination directory is unwritable: " + parent); } // if we've gotten this far then everything is ok // so we copy the file one buffer of bytes at a time FileInputStream from = null; // Stream to read from source FileOutputStream to = null; // Stream to write to destination try { from = new FileInputStream(fromFile); // Create input stream to = new FileOutputStream(toFile); // Create output stream byte[] buffer = new byte[IO_BUF_SIZE]; // to hold file data int bytesRead; // read a chunk of bytes into the buffer then write them out // looping until we reach the EOF (when read() returns -1) // Note the combination of assignment and comparison in this // while loop. This is a common I/O programming idiom. while( (bytesRead = from.read(buffer)) != -1 ) // read until EOF { to.write(buffer, 0, bytesRead); // write } } catch(IOException e) { throw( e ); } finally { if( from!=null ) { try { from.close(); } catch(IOException ex) { //throw( ex ); ex.printStackTrace(); } } if( to!=null ) { try { to.close(); } catch(IOException ex) { //throw( ex ); ex.printStackTrace(); } } } return( true ); } }