Mega Code Archive

 
Categories / Java / File Input Output
 

Utilities for file delete copy close

/*   * JBoss, Home of Professional Open Source   * Copyright 2005, JBoss Inc., and individual contributors as indicated   * by the @authors tag. See the copyright.txt in the distribution for a   * full listing of individual contributors.   *   * This 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 software 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 software; if not, write to the Free   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.   */ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.logging.Logger; /**  * A collection of file utilities.  *  * @author  <a href="mailto:jason@planet57.com">Jason Dillon</a>  * @author  <a href="mailto:Scott.Stark@jboss.org">Scott Stark<a/>  * @author  <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>  * @version $Revision: 1958 $  */ public final class Files {       /** for byte-to-hex conversions */    private static final char[] hexDigits = new char[]       { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };        /** The default size of the copy buffer. */    public static final int DEFAULT_BUFFER_SIZE = 8192;    /** Delete a file, or a directory and all of its contents.     *     * @param dir The directory or file to delete.     * @return True if all delete operations were successfull.     */    public static boolean delete(final File dir)    {       boolean success = true;       File files[] = dir.listFiles();       if (files != null)       {          for (int i = 0; i < files.length; i++)          {             File f = files[i];             if( f.isDirectory() == true )             {                // delete the directory and all of its contents.                if( delete(f) == false )                {                   success = false;                   System.out.println("Failed to delete dir: "+f.getAbsolutePath());                }             }             // delete each file in the directory             else if( f.delete() == false )             {                success = false;                System.out.println("Failed to delete file: "+f.getAbsolutePath());             }          }       }       // finally delete the directory       if( dir.delete() == false )       {          success = false;          System.out.println("Failed to delete dir: "+dir.getAbsolutePath());       }       return success;    }    /**     * Delete a file or directory and all of its contents.     *     * @param dirname  The name of the file or directory to delete.     * @return True if all delete operations were successfull.     */    public static boolean delete(final String dirname)    {       return delete(new File(dirname));    }    /**     * Delete a directory contaning the given file and all its contents.     *     * @param filename a file or directory in the containing directory to delete     * @return true if all delete operations were successfull, false if any     * delete failed.     */    public static boolean deleteContaining(final String filename)    {       File file = new File(filename);       File containingDir = file.getParentFile();       return delete(containingDir);    }    /**     * Copy a file.     *     * @param source  Source file to copy.     * @param target  Destination target file.     * @param buff    The copy buffer.     *     * @throws IOException  Failed to copy file.     */    public static void copy(final File source,          final File target,          final byte buff[])          throws IOException    {       BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));       BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(target));       int read;       try       {          while ((read = in.read(buff)) != -1)          {             out.write(buff, 0, read);          }       }       finally       {          Streams.flush(out);          Streams.close(in);          Streams.close(out);       }    }    /**     * Copy a file.     *     * @param source  Source file to copy.     * @param target  Destination target file.     * @param size    The size of the copy buffer.     *     * @throws IOException  Failed to copy file.     */    public static void copy(final File source,          final File target,          final int size)          throws IOException    {       copy(source, target, new byte[size]);    }    /**     * Copy a file.     *     * @param source  Source file to copy.     * @param target  Destination target file.     *     * @throws IOException  Failed to copy file.     */    public static void copy(final File source, final File target)          throws IOException    {       copy(source, target, DEFAULT_BUFFER_SIZE);    }        /**     * Copy a remote/local URL to a local file     *      * @param src the remote or local URL     * @param dest the local file     * @throws IOException upon error     */    public static void copy(URL src, File dest) throws IOException    {      System.out.println("Copying " + src + " -> " + dest);              // Validate that the dest parent directory structure exists       File dir = dest.getParentFile();       if (!dir.exists())       {          if (!dir.mkdirs())          {             throw new IOException("mkdirs failed for: " + dir.getAbsolutePath());          }       }       // Remove any existing dest content       if (dest.exists())       {          if (!Files.delete(dest))          {             throw new IOException("delete of previous content failed for: " + dest.getAbsolutePath());          }       }       // Treat local and remote URLs the same       // prepare streams, do the copy and flush       InputStream in = new BufferedInputStream(src.openStream());       OutputStream out = new BufferedOutputStream(new FileOutputStream(dest));       Streams.copy(in, out);       out.flush();       out.close();       in.close();    }        /**     * Used to encode any string into a string that is safe to use as      * a file name on most operating systems.     *      * Use decodeFileName() to get back the original string.     *      * Copied by Adrian's org.jboss.mq.pm.file.PersistenceManager     * and adapted to use hex instead of decimal digits     *      * @param name the filename to encode     * @return a filesystem-friendly filename     */       public static String encodeFileName(String name)    {       return encodeFileName(name, '@');    }        /**     * Used to decode a file system friendly filename produced     * by encodeFileName() method, above.     *      * Copied by Adrian's org.jboss.mq.pm.file.PersistenceManager     * and adapted to use hex instead of decimal digits     *      * Note:     *   Decoding will not work if encoding produced     *   multi-byte encoded characters. If this is truly     *   needed we'll have to revise the encoding.     *      * @param name the filename to decode     * @return the original name     */    public static String decodeFileName(String name)    {       return decodeFileName(name, '@');    }        /**     * See encodeFileName(String) above.     *      * @param name the filename to encode     * @param escape the escape character to use     * @return a filesystem-friendly filename     */     public static String encodeFileName(String name, char escape)    {       StringBuffer rc = new StringBuffer();       for (int i = 0; i < name.length(); i++ )       {          switch (name.charAt(i))          {             // These are the safe characters...             case 'a': case 'A': case 'b': case 'B': case 'c': case 'C':             case 'd': case 'D': case 'e': case 'E': case 'f': case 'F':             case 'g': case 'G': case 'h': case 'H': case 'i': case 'I':             case 'j': case 'J': case 'k': case 'K': case 'l': case 'L':             case 'm': case 'M': case 'n': case 'N': case 'o': case 'O':             case 'p': case 'P': case 'q': case 'Q': case 'r': case 'R':             case 's': case 'S': case 't': case 'T': case 'u': case 'U':             case 'v': case 'V': case 'w': case 'W': case 'x': case 'X':             case 'y': case 'Y': case 'z': case 'Z':             case '1': case '2': case '3': case '4': case '5':              case '6': case '7': case '8': case '9': case '0':              case '-': case '_': case '.':                rc.append(name.charAt(i));                break;             // Any other character needs to be encoded.             default:                             // We encode the characters as <esc>hh,                // where <esc> is the passed escape character and                // hh is the hex value of the UTF8 byte of the character.                // You might get <esc>hh<esc>hh since UTF8 can produce multiple                // bytes for a single character.                try                {                   byte data[] = ("" + name.charAt(i)).getBytes("UTF8");                   for (int j = 0; j < data.length; j++)                   {                      rc.append(escape);                      rc.append(hexDigits[ (data[j] >> 4) & 0xF ]); // high order digit                      rc.append(hexDigits[ (data[j]     ) & 0xF ]); // low order digit                                        }                }                catch (UnsupportedEncodingException wonthappen)                {                   // nada                }          }       }       return rc.toString();    }    /**     * See decodeFileName(String) above.     *       * @param name the filename to decode     * @param escape the escape character to use     * @return the original name     */    public static String decodeFileName(String name, char escape)    {       if (name == null)       {          return null;       }       StringBuffer sbuf = new StringBuffer(name.length());              for (int i = 0; i < name.length(); i++)       {          char c = name.charAt(i);          if (c == escape)          {             char h1 = name.charAt(++i);             char h2 = name.charAt(++i);             // convert hex digits to integers             int d1 = (h1 >= 'a') ? (10 + h1 - 'a')                   : ((h1 >= 'A') ? (10 + h1 - 'A')                                       :  (h1 - '0'));                          int d2 = (h2 >= 'a') ? (10 + h2 - 'a')                   : ((h2 >= 'A') ? (10 + h2 - 'A')                                       : (h2 - '0'));                          // handling only the <esc>hh case here, as we don't know             // if <esc>hh<esc>hh belong to the same character             // (and we are lazy to change the encoding) - REVISIT             byte[] bytes = new byte[] { (byte)(d1 * 16 + d2) };                          try              {                String s = new String(bytes, "UTF8");                sbuf.append(s);             }             catch (UnsupportedEncodingException wonthappen)             {                // nada             }          }          else          {             sbuf.append(c);          }       }       return sbuf.toString();    }       } final class Streams {    private static final Logger log = Logger.getLogger("Streams.class");        /////////////////////////////////////////////////////////////////////////    //                               Closing                               //    /////////////////////////////////////////////////////////////////////////    /**     * Attempt to close an <tt>InputStream</tt>.     *     * @param stream  <tt>InputStream</tt> to attempt to close.     * @return        <tt>True</tt> if stream was closed (or stream was null),     *                or <tt>false</tt> if an exception was thrown.     */    public static boolean close(final InputStream stream) {       // do not attempt to close null stream, but return sucess       if (stream == null) {          return true;       }              boolean success = true;       try {          stream.close();       }       catch (IOException e) {          success = false;       }       return success;    }    /**     * Attempt to close an <tt>OutputStream</tt>.     *     * @param stream  <tt>OutputStream</tt> to attempt to close.     * @return        <tt>True</tt> if stream was closed (or stream was null),     *                or <tt>false</tt> if an exception was thrown.     */    public static boolean close(final OutputStream stream) {       // do not attempt to close null stream, but return sucess       if (stream == null) {          return true;       }       boolean success = true;       try {          stream.close();       }       catch (IOException e) {          success = false;       }       return success;    }    /**     * Attempt to close an <tt>InputStream</tt> or <tt>OutputStream</tt>.     *     * @param stream  Stream to attempt to close.     * @return        <tt>True</tt> if stream was closed (or stream was null),     *                or <tt>false</tt> if an exception was thrown.     *     * @throws IllegalArgumentException    Stream is not an <tt>InputStream</tt>     *                                     or <tt>OuputStream</tt>.     */    public static boolean close(final Object stream) {       boolean success = false;       if (stream instanceof InputStream) {          success = close((InputStream)stream);       }       else if (stream instanceof OutputStream) {          success = close((OutputStream)stream);       }       else {          throw new IllegalArgumentException             ("stream is not an InputStream or OutputStream");       }       return success;    }    /**     * Attempt to close an array of <tt>InputStream</tt>s.     *     * @param streams Array of <tt>InputStream</tt>s to attempt to close.     * @return        <tt>True</tt> if all streams were closed, or <tt>false</tt>     *                if an exception was thrown.     */    public static boolean close(final InputStream[] streams) {       boolean success = true;       for (int i=0; i<streams.length; i++) {          boolean rv = close(streams[i]);          if (!rv) success = false;       }       return success;    }    /**     * Attempt to close an array of <tt>OutputStream</tt>s.     *     * @param streams Array of <tt>OutputStream</tt>s to attempt to close.     * @return        <tt>True</tt> if all streams were closed, or <tt>false</tt>     *                if an exception was thrown.     */    public static boolean close(final OutputStream[] streams) {       boolean success = true;       for (int i=0; i<streams.length; i++) {          boolean rv = close(streams[i]);          if (!rv) success = false;       }       return success;    }    /**     * Attempt to close an array of <tt>InputStream</tt>a and/or      * <tt>OutputStream</tt>s.     *     * @param streams Array of streams to attempt to close.     * @return        <tt>True</tt> if all streams were closed, or <tt>false</tt>     *                if an exception was thrown.     *     * @throws IllegalArgumentException    Stream is not an <tt>InputStream</tt>     *                                     or <tt>OuputStream</tt>.  Closing      *                                     stops at the last valid stream     *                                     object in this case.     */    public static boolean close(final Object[] streams) {       boolean success = true;       for (int i=0; i<streams.length; i++) {          boolean rv = close(streams[i]);          if (!rv) success = false;       }       return success;    }    /**     * Attempt to flush and close an <tt>OutputStream</tt>.     *     * @param stream  <tt>OutputStream</tt> to attempt to flush and close.     * @return        <tt>True</tt> if stream was flushed and closed, or     *                <tt>false</tt> if an exception was thrown.     */    public static boolean fclose(final OutputStream stream) {        return flush(stream) && close(stream);    }    /**     * Attempt to flush and close an array of <tt>OutputStream</tt>s.     *     * @param streams  <tt>OutputStream</tt>s to attempt to flush and close.     * @return         <tt>True</tt> if all streams were flushed and closed,      *                 or <tt>false</tt> if an exception was thrown.     */    public static boolean fclose(final OutputStream[] streams) {       boolean success = true;       for (int i=0; i<streams.length; i++) {          boolean rv = fclose(streams[i]);           if (!rv) success = false;       }       return success;    }         /////////////////////////////////////////////////////////////////////////    //                                Flushing                             //    /////////////////////////////////////////////////////////////////////////    /**     * Attempt to flush an <tt>OutputStream</tt>.     *     * @param stream  <tt>OutputStream</tt> to attempt to flush.     * @return        <tt>True</tt> if stream was flushed (or stream was null),     *                or <tt>false</tt> if an exception was thrown.     */    public static boolean flush(final OutputStream stream) {       // do not attempt to close null stream, but return sucess       if (stream == null) {          return true;       }              boolean success = true;       try {          stream.flush();       }       catch (IOException e) {          success = false;       }       return success;    }    /**     * Attempt to flush an array of <tt>OutputStream</tt>s.     *     * @param streams <tt>OutputStream</tt>s to attempt to flush.     * @return        <tt>True</tt> if all streams were flushed, or <tt>false</tt>     *                 if an exception was thrown.     */    public static boolean flush(final OutputStream[] streams) {       boolean success = true;       for (int i=0; i<streams.length; i++) {          boolean rv = flush(streams[i]);          if (!rv) success = false;       }       return success;    }    /////////////////////////////////////////////////////////////////////////    //                                  Misc                               //    /////////////////////////////////////////////////////////////////////////    /** The default buffer size that will be used for buffered operations. */    public static final int DEFAULT_BUFFER_SIZE = 2048;    /**     * Copy all of the bytes from the input stream to the output stream.     *     * @param input   Stream to read bytes from.     * @param output  Stream to write bytes to.     * @param buffer  The buffer to use while copying.     * @return        The total number of bytes copied.     *     * @throws IOException  Failed to copy bytes.     */    public static long copy(final InputStream input,                             final OutputStream output,                             final byte buffer[])       throws IOException    {       long total = 0;       int read;       System.out.println("copying " + input + " to " + output + " with buffer size: " + buffer.length);              while ((read = input.read(buffer)) != -1) {          output.write(buffer, 0, read);          total += read;          System.out.println("bytes read: " + read + "; total bytes read: " + total);       }       return total;    }    /**     * Copy all of the bytes from the input stream to the output stream.     *     * @param input   Stream to read bytes from.     * @param output  Stream to write bytes to.     * @param size    The size of the buffer to use while copying.     * @return        The total number of bytes copied.     *     * @throws IOException  Failed to copy bytes.     */    public static long copy(final InputStream input,                             final OutputStream output,                             final int size)       throws IOException    {       return copy(input, output, new byte[size]);    }    /**     * Copy all of the bytes from the input stream to the output stream.     *     * @param input   Stream to read bytes from.     * @param output  Stream to write bytes to.     * @return        The total number of bytes copied.     *     * @throws IOException  Failed to copy bytes.     */    public static long copy(final InputStream input,                             final OutputStream output)       throws IOException    {       return copy(input, output, DEFAULT_BUFFER_SIZE);    }    /**     * Copy all of the bytes from the input stream to the output stream     * wrapping streams in buffers as needed.     *     * @param input   Stream to read bytes from.     * @param output  Stream to write bytes to.     * @return        The total number of bytes copied.     *     * @throws IOException  Failed to copy bytes.     */    public static long copyb(InputStream input,                              OutputStream output)       throws IOException    {       if (!(input instanceof BufferedInputStream)) {          input = new BufferedInputStream(input);       }              if (!(output instanceof BufferedOutputStream)) {          output = new BufferedOutputStream(output);       }       long bytes = copy(input, output, DEFAULT_BUFFER_SIZE);       output.flush();       return bytes;    }        /**     * Copy a limited number of bytes from the input stream to the      * output stream.     *     * @param input   Stream to read bytes from.     * @param output  Stream to write bytes to.     * @param buffer  The buffer to use while copying.     * @param length  The maximum number of bytes to copy.     * @return        The total number of bytes copied.     *     * @throws IOException  Failed to copy bytes.     */    public static long copySome(final InputStream input,                                 final OutputStream output,                                 final byte buffer[],                                final long length)       throws IOException    {       long total = 0;       int read;       int readLength;             // setup the initial readLength, if length is less than the buffer       // size, then we only want to read that much       readLength = Math.min((int)length, buffer.length);       System.out.println("initial read length: " + readLength);       while (readLength != 0 && (read = input.read(buffer, 0, readLength)) != -1)        {         System.out.println("read bytes: " + read);          output.write(buffer, 0, read);          total += read;          System.out.println("total bytes read: " + total);          // update the readLength          readLength = Math.min((int)(length - total), buffer.length);          System.out.println("next read length: " + readLength);       }       return total;    }    /**     * Copy a limited number of bytes from the input stream to the      * output stream.     *     * @param input   Stream to read bytes from.     * @param output  Stream to write bytes to.     * @param size    The size of the buffer to use while copying.     * @param length  The maximum number of bytes to copy.     * @return        The total number of bytes copied.     *     * @throws IOException  Failed to copy bytes.     */    public static long copySome(final InputStream input,                                 final OutputStream output,                                 final int size,                                final long length)       throws IOException    {       return copySome(input, output, new byte[size], length);    }    /**     * Copy a limited number of bytes from the input stream to the      * output stream.     *     * @param input   Stream to read bytes from.     * @param output  Stream to write bytes to.     * @param length  The maximum number of bytes to copy.     * @return        The total number of bytes copied.     *     * @throws IOException  Failed to copy bytes.     */    public static long copySome(final InputStream input,                                 final OutputStream output,                                 final long length)       throws IOException    {       return copySome(input, output, DEFAULT_BUFFER_SIZE, length);    } }