Author: ggregory Date: Mon Apr 16 20:37:17 2012 New Revision: 1326785 URL: http://svn.apache.org/viewvc?rev=1326785&view=rev Log: First cut at [IO-326] Add new FileUtils.sizeOf[Directory] APIs to return BigInteger.
Modified: commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java commons/proper/io/trunk/src/test/java/org/apache/commons/io/FileUtilsTestCase.java Modified: commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java?rev=1326785&r1=1326784&r2=1326785&view=diff ============================================================================== --- commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java (original) +++ commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java Mon Apr 16 20:37:17 2012 @@ -2352,6 +2352,39 @@ public class FileUtils { } /** + * Returns the size of the specified file or directory. If the provided + * {@link File} is a regular file, then the file's length is returned. + * If the argument is a directory, then the size of the directory is + * calculated recursively. If a directory or subdirectory is security + * restricted, its size will not be included. + * + * @param file the regular file or directory to return the size + * of (must not be {@code null}). + * + * @return the length of the file, or recursive size of the directory, + * provided (in bytes). + * + * @throws NullPointerException if the file is {@code null} + * @throws IllegalArgumentException if the file does not exist. + * + * @since 2.4 + */ + public static BigInteger sizeOfAsBigInteger(File file) { + + if (!file.exists()) { + String message = file + " does not exist"; + throw new IllegalArgumentException(message); + } + + if (file.isDirectory()) { + return sizeOfDirectoryAsBigInteger(file); + } else { + return BigInteger.valueOf(file.length()); + } + + } + + /** * Counts the size of a directory recursively (sum of the length of all files). * * @param directory @@ -2362,20 +2395,14 @@ public class FileUtils { * if the directory is {@code null} */ public static long sizeOfDirectory(File directory) { - if (!directory.exists()) { - throw new IllegalArgumentException(directory + " does not exist"); - } - - if (!directory.isDirectory()) { - throw new IllegalArgumentException(directory + " is not a directory"); - } - - long size = 0; + checkDirectory(directory); final File[] files = directory.listFiles(); if (files == null) { // null if security restricted return 0L; } + long size = 0; + for (final File file : files) { try { if (!isSymlink(file)) { @@ -2392,6 +2419,48 @@ public class FileUtils { return size; } + /** + * Counts the size of a directory recursively (sum of the length of all files). + * + * @param directory + * directory to inspect, must not be {@code null} + * @return size of directory in bytes, 0 if directory is security restricted. + * @throws NullPointerException + * if the directory is {@code null} + * @since 2.4 + */ + public static BigInteger sizeOfDirectoryAsBigInteger(File directory) { + checkDirectory(directory); + + final File[] files = directory.listFiles(); + if (files == null) { // null if security restricted + return BigInteger.ZERO; + } + BigInteger size = BigInteger.ZERO; + + for (final File file : files) { + try { + if (!isSymlink(file)) { + size.add(BigInteger.valueOf(sizeOf(file))); + } + } catch (IOException ioe) { + // Ignore exceptions caught when asking if a File is a symlink. + } + } + + return size; + } + + private static void checkDirectory(File directory) { + if (!directory.exists()) { + throw new IllegalArgumentException(directory + " does not exist"); + } + + if (!directory.isDirectory()) { + throw new IllegalArgumentException(directory + " is not a directory"); + } + } + //----------------------------------------------------------------------- /** * Tests if the specified <code>File</code> is newer than the reference Modified: commons/proper/io/trunk/src/test/java/org/apache/commons/io/FileUtilsTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/FileUtilsTestCase.java?rev=1326785&r1=1326784&r2=1326785&view=diff ============================================================================== --- commons/proper/io/trunk/src/test/java/org/apache/commons/io/FileUtilsTestCase.java (original) +++ commons/proper/io/trunk/src/test/java/org/apache/commons/io/FileUtilsTestCase.java Mon Apr 16 20:37:17 2012 @@ -23,6 +23,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.math.BigInteger; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; @@ -58,6 +59,11 @@ public class FileUtilsTestCase extends F private static final int TEST_DIRECTORY_SIZE = 0; /** + * Size of test directory. + */ + private static final BigInteger TEST_DIRECTORY_SIZE_BI = BigInteger.ZERO; + + /** * List files recursively */ private static final ListDirectoryWalker LIST_WALKER = new ListDirectoryWalker(); @@ -713,6 +719,15 @@ public class FileUtilsTestCase extends F file.mkdir(); // Create a cyclic symlink + this.createCircularSymLink(file); + + assertEquals( + "Unexpected directory size", + TEST_DIRECTORY_SIZE, + FileUtils.sizeOfDirectory(file)); + } + + private void createCircularSymLink(File file) throws IOException { if(!FilenameUtils.isSystemWindows()) { Runtime.getRuntime() .exec("ln -s " + file + "/.. " + file + "/cycle"); @@ -724,11 +739,37 @@ public class FileUtilsTestCase extends F //don't fail } } + } + + public void testSizeOfDirectoryAsBigInteger() throws Exception { + File file = new File(getTestDirectory(), getName()); + + // Non-existent file + try { + FileUtils.sizeOfDirectoryAsBigInteger(file); + fail("Exception expected."); + } catch (IllegalArgumentException ex) {} + + // Creates file + file.createNewFile(); + file.deleteOnExit(); + + // Existing file + try { + FileUtils.sizeOfDirectoryAsBigInteger(file); + fail("Exception expected."); + } catch (IllegalArgumentException ex) {} + + // Existing directory + file.delete(); + file.mkdir(); + + this.createCircularSymLink(file); assertEquals( "Unexpected directory size", - TEST_DIRECTORY_SIZE, - FileUtils.sizeOfDirectory(file)); + TEST_DIRECTORY_SIZE_BI, + FileUtils.sizeOfDirectoryAsBigInteger(file)); } /** @@ -769,6 +810,44 @@ public class FileUtilsTestCase extends F FileUtils.sizeOf(getTestDirectory())); } + /** + * Tests the {@link FileUtils#sizeOf(File)} method. + * @throws Exception + */ + public void testSizeOfAsBigInteger() throws Exception { + File file = new File(getTestDirectory(), getName()); + + // Null argument + try { + FileUtils.sizeOfAsBigInteger(null); + fail("Exception expected."); + } catch (NullPointerException ex) {} + + // Non-existent file + try { + FileUtils.sizeOfAsBigInteger(file); + fail("Exception expected."); + } catch (IllegalArgumentException ex) {} + + // Creates file + file.createNewFile(); + file.deleteOnExit(); + + // New file + assertEquals(BigInteger.ZERO, FileUtils.sizeOfAsBigInteger(file)); + file.delete(); + + // Existing file + assertEquals("Unexpected files size", + BigInteger.valueOf(testFile1Size), + FileUtils.sizeOfAsBigInteger(testFile1)); + + // Existing directory + assertEquals("Unexpected directory size", + TEST_DIRECTORY_SIZE_BI, + FileUtils.sizeOfAsBigInteger(getTestDirectory())); + } + // isFileNewer / isFileOlder public void testIsFileNewerOlder() throws Exception { File reference = new File(getTestDirectory(), "FileUtils-reference.txt");