~ubuntu-branches/ubuntu/quantal/commons-io/quantal

« back to all changes in this revision

Viewing changes to src/java/org/apache/commons/io/FileUtils.java

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2008-02-21 13:26:43 UTC
  • mfrom: (1.1.3 upstream) (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080221132643-p4c8f8lhb9rnqnlo
Tags: 1.4-1
* New upstream release
* Bump Standards-Version to 3.7.3
* Bump up debhelper compat to 6
* Replace XS-Vcs headers with Vcs
* debian/patches:
  - remove 01_no_ext_links.dpatch - not required
  - remove 02_no_mkdir_in_homedir.dpatch - not required
* Remove dpatch from Build-Depends
* Update debian/rules and debian/libcommons-io-java-doc.install
  with new target dirs
* debian/copyright: add copyright notice

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
import java.io.InputStream;
26
26
import java.io.OutputStream;
27
27
import java.net.URL;
 
28
import java.util.ArrayList;
28
29
import java.util.Collection;
29
30
import java.util.Date;
30
31
import java.util.Iterator;
74
75
 * @author Jim Harrington
75
76
 * @author Niall Pemberton
76
77
 * @author Sandy McArthur
77
 
 * @version $Id: FileUtils.java 507684 2007-02-14 20:38:25Z bayard $
 
78
 * @version $Id: FileUtils.java 610810 2008-01-10 15:04:49Z niallp $
78
79
 */
79
80
public class FileUtils {
80
81
 
397
398
 
398
399
    //-----------------------------------------------------------------------
399
400
    /**
400
 
     * Compare the contents of two files to determine if they are equal or not.
 
401
     * Compares the contents of two files to determine if they are equal or not.
401
402
     * <p>
402
403
     * This method checks to see if the two files are different lengths
403
404
     * or if they point to the same file, before resorting to byte-by-byte
766
767
     */
767
768
    public static void copyDirectory(File srcDir, File destDir,
768
769
            boolean preserveFileDate) throws IOException {
 
770
        copyDirectory(srcDir, destDir, null, preserveFileDate);
 
771
    }
 
772
 
 
773
    /**
 
774
     * Copies a filtered directory to a new location preserving the file dates.
 
775
     * <p>
 
776
     * This method copies the contents of the specified source directory
 
777
     * to within the specified destination directory.
 
778
     * <p>
 
779
     * The destination directory is created if it does not exist.
 
780
     * If the destination directory did exist, then this method merges
 
781
     * the source with the destination, with the source taking precedence.
 
782
     *
 
783
     * <h4>Example: Copy directories only</h4> 
 
784
     *  <pre>
 
785
     *  // only copy the directory structure
 
786
     *  FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY);
 
787
     *  </pre>
 
788
     *
 
789
     * <h4>Example: Copy directories and txt files</h4>
 
790
     *  <pre>
 
791
     *  // Create a filter for ".txt" files
 
792
     *  IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
 
793
     *  IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
 
794
     *
 
795
     *  // Create a filter for either directories or ".txt" files
 
796
     *  FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
 
797
     *
 
798
     *  // Copy using the filter
 
799
     *  FileUtils.copyDirectory(srcDir, destDir, filter);
 
800
     *  </pre>
 
801
     *
 
802
     * @param srcDir  an existing directory to copy, must not be <code>null</code>
 
803
     * @param destDir  the new directory, must not be <code>null</code>
 
804
     * @param filter  the filter to apply, null means copy all directories and files
 
805
     *  should be the same as the original
 
806
     *
 
807
     * @throws NullPointerException if source or destination is <code>null</code>
 
808
     * @throws IOException if source or destination is invalid
 
809
     * @throws IOException if an IO error occurs during copying
 
810
     * @since Commons IO 1.4
 
811
     */
 
812
    public static void copyDirectory(File srcDir, File destDir,
 
813
            FileFilter filter) throws IOException {
 
814
        copyDirectory(srcDir, destDir, filter, true);
 
815
    }
 
816
 
 
817
    /**
 
818
     * Copies a filtered directory to a new location.
 
819
     * <p>
 
820
     * This method copies the contents of the specified source directory
 
821
     * to within the specified destination directory.
 
822
     * <p>
 
823
     * The destination directory is created if it does not exist.
 
824
     * If the destination directory did exist, then this method merges
 
825
     * the source with the destination, with the source taking precedence.
 
826
     *
 
827
     * <h4>Example: Copy directories only</h4> 
 
828
     *  <pre>
 
829
     *  // only copy the directory structure
 
830
     *  FileUtils.copyDirectory(srcDir, destDir, DirectoryFileFilter.DIRECTORY, false);
 
831
     *  </pre>
 
832
     *
 
833
     * <h4>Example: Copy directories and txt files</h4>
 
834
     *  <pre>
 
835
     *  // Create a filter for ".txt" files
 
836
     *  IOFileFilter txtSuffixFilter = FileFilterUtils.suffixFileFilter(".txt");
 
837
     *  IOFileFilter txtFiles = FileFilterUtils.andFileFilter(FileFileFilter.FILE, txtSuffixFilter);
 
838
     *
 
839
     *  // Create a filter for either directories or ".txt" files
 
840
     *  FileFilter filter = FileFilterUtils.orFileFilter(DirectoryFileFilter.DIRECTORY, txtFiles);
 
841
     *
 
842
     *  // Copy using the filter
 
843
     *  FileUtils.copyDirectory(srcDir, destDir, filter, false);
 
844
     *  </pre>
 
845
     * 
 
846
     * @param srcDir  an existing directory to copy, must not be <code>null</code>
 
847
     * @param destDir  the new directory, must not be <code>null</code>
 
848
     * @param filter  the filter to apply, null means copy all directories and files
 
849
     * @param preserveFileDate  true if the file date of the copy
 
850
     *  should be the same as the original
 
851
     *
 
852
     * @throws NullPointerException if source or destination is <code>null</code>
 
853
     * @throws IOException if source or destination is invalid
 
854
     * @throws IOException if an IO error occurs during copying
 
855
     * @since Commons IO 1.4
 
856
     */
 
857
    public static void copyDirectory(File srcDir, File destDir,
 
858
            FileFilter filter, boolean preserveFileDate) throws IOException {
769
859
        if (srcDir == null) {
770
860
            throw new NullPointerException("Source must not be null");
771
861
        }
781
871
        if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath())) {
782
872
            throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same");
783
873
        }
784
 
        doCopyDirectory(srcDir, destDir, preserveFileDate);
 
874
 
 
875
        // Cater for destination being directory within the source directory (see IO-141)
 
876
        List exclusionList = null;
 
877
        if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) {
 
878
            File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
 
879
            if (srcFiles != null && srcFiles.length > 0) {
 
880
                exclusionList = new ArrayList(srcFiles.length);
 
881
                for (int i = 0; i < srcFiles.length; i++) {
 
882
                    File copiedFile = new File(destDir, srcFiles[i].getName());
 
883
                    exclusionList.add(copiedFile.getCanonicalPath());
 
884
                }
 
885
            }
 
886
        }
 
887
        doCopyDirectory(srcDir, destDir, filter, preserveFileDate, exclusionList);
785
888
    }
786
889
 
787
890
    /**
789
892
     * 
790
893
     * @param srcDir  the validated source directory, must not be <code>null</code>
791
894
     * @param destDir  the validated destination directory, must not be <code>null</code>
 
895
     * @param filter  the filter to apply, null means copy all directories and files
792
896
     * @param preserveFileDate  whether to preserve the file date
 
897
     * @param exclusionList  List of files and directories to exclude from the copy, may be null
793
898
     * @throws IOException if an error occurs
794
899
     * @since Commons IO 1.1
795
900
     */
796
 
    private static void doCopyDirectory(File srcDir, File destDir, boolean preserveFileDate) throws IOException {
 
901
    private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter,
 
902
            boolean preserveFileDate, List exclusionList) throws IOException {
797
903
        if (destDir.exists()) {
798
904
            if (destDir.isDirectory() == false) {
799
905
                throw new IOException("Destination '" + destDir + "' exists but is not a directory");
810
916
            throw new IOException("Destination '" + destDir + "' cannot be written to");
811
917
        }
812
918
        // recurse
813
 
        File[] files = srcDir.listFiles();
 
919
        File[] files = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
814
920
        if (files == null) {  // null if security restricted
815
921
            throw new IOException("Failed to list contents of " + srcDir);
816
922
        }
817
923
        for (int i = 0; i < files.length; i++) {
818
924
            File copiedFile = new File(destDir, files[i].getName());
819
 
            if (files[i].isDirectory()) {
820
 
                doCopyDirectory(files[i], copiedFile, preserveFileDate);
821
 
            } else {
822
 
                doCopyFile(files[i], copiedFile, preserveFileDate);
 
925
            if (exclusionList == null || !exclusionList.contains(files[i].getCanonicalPath())) {
 
926
                if (files[i].isDirectory()) {
 
927
                    doCopyDirectory(files[i], copiedFile, filter, preserveFileDate, exclusionList);
 
928
                } else {
 
929
                    doCopyFile(files[i], copiedFile, preserveFileDate);
 
930
                }
823
931
            }
824
932
        }
825
933
    }
856
964
 
857
965
    //-----------------------------------------------------------------------
858
966
    /**
859
 
     * Recursively delete a directory.
 
967
     * Deletes a directory recursively. 
860
968
     *
861
969
     * @param directory  directory to delete
862
970
     * @throws IOException in case deletion is unsuccessful
875
983
    }
876
984
 
877
985
    /**
878
 
     * Clean a directory without deleting it.
 
986
     * Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.
 
987
     * <p>
 
988
     * The difference between File.delete() and this method are:
 
989
     * <ul>
 
990
     * <li>A directory to be deleted does not have to be empty.</li>
 
991
     * <li>No exceptions are thrown when a file or directory cannot be deleted.</li>
 
992
     * </ul>
 
993
     *
 
994
     * @param file  file or directory to delete, can be <code>null</code>
 
995
     * @return <code>true</code> if the file or directory was deleted, otherwise
 
996
     * <code>false</code>
 
997
     *
 
998
     * @since Commons IO 1.4
 
999
     */
 
1000
    public static boolean deleteQuietly(File file) {
 
1001
        if (file == null) {
 
1002
            return false;
 
1003
        }
 
1004
        try {
 
1005
            if (file.isDirectory()) {
 
1006
                cleanDirectory(file);
 
1007
            }
 
1008
        } catch (Exception e) {
 
1009
        }
 
1010
 
 
1011
        try {
 
1012
            return file.delete();
 
1013
        } catch (Exception e) {
 
1014
            return false;
 
1015
        }
 
1016
    }
 
1017
 
 
1018
    /**
 
1019
     * Cleans a directory without deleting it.
879
1020
     *
880
1021
     * @param directory directory to clean
881
1022
     * @throws IOException in case cleaning is unsuccessful
1033
1174
    }
1034
1175
 
1035
1176
    /**
1036
 
     * Return an Iterator for the lines in a <code>File</code>.
 
1177
     * Returns an Iterator for the lines in a <code>File</code>.
1037
1178
     * <p>
1038
1179
     * This method opens an <code>InputStream</code> for the file.
1039
1180
     * When you have finished with the iterator you should close the stream
1078
1219
    }
1079
1220
 
1080
1221
    /**
1081
 
     * Return an Iterator for the lines in a <code>File</code> using the default encoding for the VM.
 
1222
     * Returns an Iterator for the lines in a <code>File</code> using the default encoding for the VM.
1082
1223
     *
1083
1224
     * @param file  the file to open for input, must not be <code>null</code>
1084
1225
     * @return an Iterator of the lines in the file, never <code>null</code>
1221
1362
 
1222
1363
    //-----------------------------------------------------------------------
1223
1364
    /**
1224
 
     * Delete a file. If file is a directory, delete it and all sub-directories.
 
1365
     * Deletes a file. If file is a directory, delete it and all sub-directories.
1225
1366
     * <p>
1226
1367
     * The difference between File.delete() and this method are:
1227
1368
     * <ul>
1232
1373
     *
1233
1374
     * @param file  file or directory to delete, must not be <code>null</code>
1234
1375
     * @throws NullPointerException if the directory is <code>null</code>
 
1376
     * @throws FileNotFoundException if the file was not found
1235
1377
     * @throws IOException in case deletion is unsuccessful
1236
1378
     */
1237
1379
    public static void forceDelete(File file) throws IOException {
1238
1380
        if (file.isDirectory()) {
1239
1381
            deleteDirectory(file);
1240
1382
        } else {
1241
 
            if (!file.exists()) {
1242
 
                throw new FileNotFoundException("File does not exist: " + file);
1243
 
            }
 
1383
            boolean filePresent = file.exists();
1244
1384
            if (!file.delete()) {
 
1385
                if (!filePresent){
 
1386
                    throw new FileNotFoundException("File does not exist: " + file);
 
1387
                }
1245
1388
                String message =
1246
1389
                    "Unable to delete file: " + file;
1247
1390
                throw new IOException(message);
1250
1393
    }
1251
1394
 
1252
1395
    /**
1253
 
     * Schedule a file to be deleted when JVM exits.
 
1396
     * Schedules a file to be deleted when JVM exits.
1254
1397
     * If file is directory delete it and all sub-directories.
1255
1398
     *
1256
1399
     * @param file  file or directory to delete, must not be <code>null</code>
1266
1409
    }
1267
1410
 
1268
1411
    /**
1269
 
     * Recursively schedule directory for deletion on JVM exit.
 
1412
     * Schedules a directory recursively for deletion on JVM exit.
1270
1413
     *
1271
1414
     * @param directory  directory to delete, must not be <code>null</code>
1272
1415
     * @throws NullPointerException if the directory is <code>null</code>
1282
1425
    }
1283
1426
 
1284
1427
    /**
1285
 
     * Clean a directory without deleting it.
 
1428
     * Cleans a directory without deleting it.
1286
1429
     *
1287
1430
     * @param directory  directory to clean, must not be <code>null</code>
1288
1431
     * @throws NullPointerException if the directory is <code>null</code>
1320
1463
    }
1321
1464
 
1322
1465
    /**
1323
 
     * Make a directory, including any necessary but nonexistent parent
 
1466
     * Makes a directory, including any necessary but nonexistent parent
1324
1467
     * directories. If there already exists a file with specified name or
1325
1468
     * the directory cannot be created then an exception is thrown.
1326
1469
     *
1349
1492
 
1350
1493
    //-----------------------------------------------------------------------
1351
1494
    /**
1352
 
     * Recursively count size of a directory (sum of the length of all files).
 
1495
     * Counts the size of a directory recursively (sum of the length of all files).
1353
1496
     *
1354
1497
     * @param directory  directory to inspect, must not be <code>null</code>
1355
1498
     * @return size of directory in bytes, 0 if directory is security restricted
1567
1710
        return checksum;
1568
1711
    }
1569
1712
 
 
1713
    /**
 
1714
     * Moves a directory.
 
1715
     * <p>
 
1716
     * When the destination directory is on another file system, do a "copy and delete".
 
1717
     *
 
1718
     * @param srcDir the directory to be moved
 
1719
     * @param destDir the destination directory
 
1720
     * @throws NullPointerException if source or destination is <code>null</code>
 
1721
     * @throws IOException if source or destination is invalid
 
1722
     * @throws IOException if an IO error occurs moving the file
 
1723
     * @since Commons IO 1.4
 
1724
     */
 
1725
    public static void moveDirectory(File srcDir, File destDir) throws IOException {
 
1726
        if (srcDir == null) {
 
1727
            throw new NullPointerException("Source must not be null");
 
1728
        }
 
1729
        if (destDir == null) {
 
1730
            throw new NullPointerException("Destination must not be null");
 
1731
        }
 
1732
        if (!srcDir.exists()) {
 
1733
            throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
 
1734
        }
 
1735
        if (!srcDir.isDirectory()) {
 
1736
            throw new IOException("Source '" + srcDir + "' is not a directory");
 
1737
        }
 
1738
        if (destDir.exists()) {
 
1739
            throw new IOException("Destination '" + destDir + "' already exists");
 
1740
        }
 
1741
        boolean rename = srcDir.renameTo(destDir);
 
1742
        if (!rename) {
 
1743
            copyDirectory( srcDir, destDir );
 
1744
            deleteDirectory( srcDir );
 
1745
            if (srcDir.exists()) {
 
1746
                throw new IOException("Failed to delete original directory '" + srcDir +
 
1747
                        "' after copy to '" + destDir + "'");
 
1748
            }
 
1749
        }
 
1750
    }
 
1751
 
 
1752
    /**
 
1753
     * Moves a directory to another directory.
 
1754
     *
 
1755
     * @param src the file to be moved
 
1756
     * @param destDir the destination file
 
1757
     * @param createDestDir If <code>true</code> create the destination directory,
 
1758
     * otherwise if <code>false</code> throw an IOException
 
1759
     * @throws NullPointerException if source or destination is <code>null</code>
 
1760
     * @throws IOException if source or destination is invalid
 
1761
     * @throws IOException if an IO error occurs moving the file
 
1762
     * @since Commons IO 1.4
 
1763
     */
 
1764
    public static void moveDirectoryToDirectory(File src, File destDir, boolean createDestDir) throws IOException {
 
1765
        if (src == null) {
 
1766
            throw new NullPointerException("Source must not be null");
 
1767
        }
 
1768
        if (destDir == null) {
 
1769
            throw new NullPointerException("Destination directory must not be null");
 
1770
        }
 
1771
        if (!destDir.exists() && createDestDir) {
 
1772
            destDir.mkdirs();
 
1773
        }
 
1774
        if (!destDir.exists()) {
 
1775
            throw new FileNotFoundException("Destination directory '" + destDir +
 
1776
                    "' does not exist [createDestDir=" + createDestDir +"]");
 
1777
        }
 
1778
        if (!destDir.isDirectory()) {
 
1779
            throw new IOException("Destination '" + destDir + "' is not a directory");
 
1780
        }
 
1781
        moveDirectory(src, new File(destDir, src.getName()));
 
1782
    
 
1783
    }
 
1784
 
 
1785
    /**
 
1786
     * Moves a file.
 
1787
     * <p>
 
1788
     * When the destination file is on another file system, do a "copy and delete".
 
1789
     *
 
1790
     * @param srcFile the file to be moved
 
1791
     * @param destFile the destination file
 
1792
     * @throws NullPointerException if source or destination is <code>null</code>
 
1793
     * @throws IOException if source or destination is invalid
 
1794
     * @throws IOException if an IO error occurs moving the file
 
1795
     * @since Commons IO 1.4
 
1796
     */
 
1797
    public static void moveFile(File srcFile, File destFile) throws IOException {
 
1798
        if (srcFile == null) {
 
1799
            throw new NullPointerException("Source must not be null");
 
1800
        }
 
1801
        if (destFile == null) {
 
1802
            throw new NullPointerException("Destination must not be null");
 
1803
        }
 
1804
        if (!srcFile.exists()) {
 
1805
            throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
 
1806
        }
 
1807
        if (srcFile.isDirectory()) {
 
1808
            throw new IOException("Source '" + srcFile + "' is a directory");
 
1809
        }
 
1810
        if (destFile.exists()) {
 
1811
            throw new IOException("Destination '" + destFile + "' already exists");
 
1812
        }
 
1813
        if (destFile.isDirectory()) {
 
1814
            throw new IOException("Destination '" + destFile + "' is a directory");
 
1815
        }
 
1816
        boolean rename = srcFile.renameTo(destFile);
 
1817
        if (!rename) {
 
1818
            copyFile( srcFile, destFile );
 
1819
            if (!srcFile.delete()) {
 
1820
                FileUtils.deleteQuietly(destFile);
 
1821
                throw new IOException("Failed to delete original file '" + srcFile +
 
1822
                        "' after copy to '" + destFile + "'");
 
1823
            }
 
1824
        }
 
1825
    }
 
1826
 
 
1827
    /**
 
1828
     * Moves a file to a directory.
 
1829
     *
 
1830
     * @param srcFile the file to be moved
 
1831
     * @param destDir the destination file
 
1832
     * @param createDestDir If <code>true</code> create the destination directory,
 
1833
     * otherwise if <code>false</code> throw an IOException
 
1834
     * @throws NullPointerException if source or destination is <code>null</code>
 
1835
     * @throws IOException if source or destination is invalid
 
1836
     * @throws IOException if an IO error occurs moving the file
 
1837
     * @since Commons IO 1.4
 
1838
     */
 
1839
    public static void moveFileToDirectory(File srcFile, File destDir, boolean createDestDir) throws IOException {
 
1840
        if (srcFile == null) {
 
1841
            throw new NullPointerException("Source must not be null");
 
1842
        }
 
1843
        if (destDir == null) {
 
1844
            throw new NullPointerException("Destination directory must not be null");
 
1845
        }
 
1846
        if (!destDir.exists() && createDestDir) {
 
1847
            destDir.mkdirs();
 
1848
        }
 
1849
        if (!destDir.exists()) {
 
1850
            throw new FileNotFoundException("Destination directory '" + destDir +
 
1851
                    "' does not exist [createDestDir=" + createDestDir +"]");
 
1852
        }
 
1853
        if (!destDir.isDirectory()) {
 
1854
            throw new IOException("Destination '" + destDir + "' is not a directory");
 
1855
        }
 
1856
        moveFile(srcFile, new File(destDir, srcFile.getName()));
 
1857
    }
 
1858
 
 
1859
    /**
 
1860
     * Moves a file or directory to the destination directory.
 
1861
     * <p>
 
1862
     * When the destination is on another file system, do a "copy and delete".
 
1863
     *
 
1864
     * @param src the file or directory to be moved
 
1865
     * @param destDir the destination directory 
 
1866
     * @param createDestDir If <code>true</code> create the destination directory,
 
1867
     * otherwise if <code>false</code> throw an IOException
 
1868
     * @throws NullPointerException if source or destination is <code>null</code>
 
1869
     * @throws IOException if source or destination is invalid
 
1870
     * @throws IOException if an IO error occurs moving the file
 
1871
     * @since Commons IO 1.4
 
1872
     */
 
1873
    public static void moveToDirectory(File src, File destDir, boolean createDestDir) throws IOException {
 
1874
        if (src == null) {
 
1875
            throw new NullPointerException("Source must not be null");
 
1876
        }
 
1877
        if (destDir == null) {
 
1878
            throw new NullPointerException("Destination must not be null");
 
1879
        }
 
1880
        if (!src.exists()) {
 
1881
            throw new FileNotFoundException("Source '" + src + "' does not exist");
 
1882
        }
 
1883
        if (src.isDirectory()) {
 
1884
            moveDirectoryToDirectory(src, destDir, createDestDir);
 
1885
        } else {
 
1886
            moveFileToDirectory(src, destDir, createDestDir);
 
1887
        }
 
1888
    }
 
1889
 
1570
1890
}