Skip to content

Commit 27830ee

Browse files
committed
First cut at [IO-326] Add new FileUtils.sizeOf[Directory] APIs to return BigInteger.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/io/trunk@1326785 13f79535-47bb-0310-9956-ffa450edef68
1 parent 26dba5e commit 27830ee

2 files changed

Lines changed: 159 additions & 11 deletions

File tree

src/main/java/org/apache/commons/io/FileUtils.java

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,6 +2351,39 @@ public static long sizeOf(File file) {
23512351

23522352
}
23532353

2354+
/**
2355+
* Returns the size of the specified file or directory. If the provided
2356+
* {@link File} is a regular file, then the file's length is returned.
2357+
* If the argument is a directory, then the size of the directory is
2358+
* calculated recursively. If a directory or subdirectory is security
2359+
* restricted, its size will not be included.
2360+
*
2361+
* @param file the regular file or directory to return the size
2362+
* of (must not be {@code null}).
2363+
*
2364+
* @return the length of the file, or recursive size of the directory,
2365+
* provided (in bytes).
2366+
*
2367+
* @throws NullPointerException if the file is {@code null}
2368+
* @throws IllegalArgumentException if the file does not exist.
2369+
*
2370+
* @since 2.4
2371+
*/
2372+
public static BigInteger sizeOfAsBigInteger(File file) {
2373+
2374+
if (!file.exists()) {
2375+
String message = file + " does not exist";
2376+
throw new IllegalArgumentException(message);
2377+
}
2378+
2379+
if (file.isDirectory()) {
2380+
return sizeOfDirectoryAsBigInteger(file);
2381+
} else {
2382+
return BigInteger.valueOf(file.length());
2383+
}
2384+
2385+
}
2386+
23542387
/**
23552388
* Counts the size of a directory recursively (sum of the length of all files).
23562389
*
@@ -2362,20 +2395,14 @@ public static long sizeOf(File file) {
23622395
* if the directory is {@code null}
23632396
*/
23642397
public static long sizeOfDirectory(File directory) {
2365-
if (!directory.exists()) {
2366-
throw new IllegalArgumentException(directory + " does not exist");
2367-
}
2368-
2369-
if (!directory.isDirectory()) {
2370-
throw new IllegalArgumentException(directory + " is not a directory");
2371-
}
2372-
2373-
long size = 0;
2398+
checkDirectory(directory);
23742399

23752400
final File[] files = directory.listFiles();
23762401
if (files == null) { // null if security restricted
23772402
return 0L;
23782403
}
2404+
long size = 0;
2405+
23792406
for (final File file : files) {
23802407
try {
23812408
if (!isSymlink(file)) {
@@ -2392,6 +2419,48 @@ public static long sizeOfDirectory(File directory) {
23922419
return size;
23932420
}
23942421

2422+
/**
2423+
* Counts the size of a directory recursively (sum of the length of all files).
2424+
*
2425+
* @param directory
2426+
* directory to inspect, must not be {@code null}
2427+
* @return size of directory in bytes, 0 if directory is security restricted.
2428+
* @throws NullPointerException
2429+
* if the directory is {@code null}
2430+
* @since 2.4
2431+
*/
2432+
public static BigInteger sizeOfDirectoryAsBigInteger(File directory) {
2433+
checkDirectory(directory);
2434+
2435+
final File[] files = directory.listFiles();
2436+
if (files == null) { // null if security restricted
2437+
return BigInteger.ZERO;
2438+
}
2439+
BigInteger size = BigInteger.ZERO;
2440+
2441+
for (final File file : files) {
2442+
try {
2443+
if (!isSymlink(file)) {
2444+
size.add(BigInteger.valueOf(sizeOf(file)));
2445+
}
2446+
} catch (IOException ioe) {
2447+
// Ignore exceptions caught when asking if a File is a symlink.
2448+
}
2449+
}
2450+
2451+
return size;
2452+
}
2453+
2454+
private static void checkDirectory(File directory) {
2455+
if (!directory.exists()) {
2456+
throw new IllegalArgumentException(directory + " does not exist");
2457+
}
2458+
2459+
if (!directory.isDirectory()) {
2460+
throw new IllegalArgumentException(directory + " is not a directory");
2461+
}
2462+
}
2463+
23952464
//-----------------------------------------------------------------------
23962465
/**
23972466
* Tests if the specified <code>File</code> is newer than the reference

src/test/java/org/apache/commons/io/FileUtilsTestCase.java

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.io.FileOutputStream;
2424
import java.io.IOException;
2525
import java.io.OutputStream;
26+
import java.math.BigInteger;
2627
import java.net.URL;
2728
import java.nio.charset.Charset;
2829
import java.util.ArrayList;
@@ -57,6 +58,11 @@ public class FileUtilsTestCase extends FileBasedTestCase {
5758
*/
5859
private static final int TEST_DIRECTORY_SIZE = 0;
5960

61+
/**
62+
* Size of test directory.
63+
*/
64+
private static final BigInteger TEST_DIRECTORY_SIZE_BI = BigInteger.ZERO;
65+
6066
/**
6167
* List files recursively
6268
*/
@@ -713,6 +719,15 @@ public void testSizeOfDirectory() throws Exception {
713719
file.mkdir();
714720

715721
// Create a cyclic symlink
722+
this.createCircularSymLink(file);
723+
724+
assertEquals(
725+
"Unexpected directory size",
726+
TEST_DIRECTORY_SIZE,
727+
FileUtils.sizeOfDirectory(file));
728+
}
729+
730+
private void createCircularSymLink(File file) throws IOException {
716731
if(!FilenameUtils.isSystemWindows()) {
717732
Runtime.getRuntime()
718733
.exec("ln -s " + file + "/.. " + file + "/cycle");
@@ -724,11 +739,37 @@ public void testSizeOfDirectory() throws Exception {
724739
//don't fail
725740
}
726741
}
742+
}
743+
744+
public void testSizeOfDirectoryAsBigInteger() throws Exception {
745+
File file = new File(getTestDirectory(), getName());
746+
747+
// Non-existent file
748+
try {
749+
FileUtils.sizeOfDirectoryAsBigInteger(file);
750+
fail("Exception expected.");
751+
} catch (IllegalArgumentException ex) {}
752+
753+
// Creates file
754+
file.createNewFile();
755+
file.deleteOnExit();
756+
757+
// Existing file
758+
try {
759+
FileUtils.sizeOfDirectoryAsBigInteger(file);
760+
fail("Exception expected.");
761+
} catch (IllegalArgumentException ex) {}
762+
763+
// Existing directory
764+
file.delete();
765+
file.mkdir();
766+
767+
this.createCircularSymLink(file);
727768

728769
assertEquals(
729770
"Unexpected directory size",
730-
TEST_DIRECTORY_SIZE,
731-
FileUtils.sizeOfDirectory(file));
771+
TEST_DIRECTORY_SIZE_BI,
772+
FileUtils.sizeOfDirectoryAsBigInteger(file));
732773
}
733774

734775
/**
@@ -769,6 +810,44 @@ public void testSizeOf() throws Exception {
769810
FileUtils.sizeOf(getTestDirectory()));
770811
}
771812

813+
/**
814+
* Tests the {@link FileUtils#sizeOf(File)} method.
815+
* @throws Exception
816+
*/
817+
public void testSizeOfAsBigInteger() throws Exception {
818+
File file = new File(getTestDirectory(), getName());
819+
820+
// Null argument
821+
try {
822+
FileUtils.sizeOfAsBigInteger(null);
823+
fail("Exception expected.");
824+
} catch (NullPointerException ex) {}
825+
826+
// Non-existent file
827+
try {
828+
FileUtils.sizeOfAsBigInteger(file);
829+
fail("Exception expected.");
830+
} catch (IllegalArgumentException ex) {}
831+
832+
// Creates file
833+
file.createNewFile();
834+
file.deleteOnExit();
835+
836+
// New file
837+
assertEquals(BigInteger.ZERO, FileUtils.sizeOfAsBigInteger(file));
838+
file.delete();
839+
840+
// Existing file
841+
assertEquals("Unexpected files size",
842+
BigInteger.valueOf(testFile1Size),
843+
FileUtils.sizeOfAsBigInteger(testFile1));
844+
845+
// Existing directory
846+
assertEquals("Unexpected directory size",
847+
TEST_DIRECTORY_SIZE_BI,
848+
FileUtils.sizeOfAsBigInteger(getTestDirectory()));
849+
}
850+
772851
// isFileNewer / isFileOlder
773852
public void testIsFileNewerOlder() throws Exception {
774853
File reference = new File(getTestDirectory(), "FileUtils-reference.txt");

0 commit comments

Comments
 (0)