You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2012/03/01 18:45:12 UTC

svn commit: r1295700 - in /commons/proper/io/trunk/src: changes/changes.xml main/java/org/apache/commons/io/FileUtils.java test/java/org/apache/commons/io/FileUtilsTestCase.java

Author: sebb
Date: Thu Mar  1 17:45:11 2012
New Revision: 1295700

URL: http://svn.apache.org/viewvc?rev=1295700&view=rev
Log:
IO-173 FileUtils.listFiles() doesn't return directories

Modified:
    commons/proper/io/trunk/src/changes/changes.xml
    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/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/changes/changes.xml?rev=1295700&r1=1295699&r2=1295700&view=diff
==============================================================================
--- commons/proper/io/trunk/src/changes/changes.xml (original)
+++ commons/proper/io/trunk/src/changes/changes.xml Thu Mar  1 17:45:11 2012
@@ -40,6 +40,9 @@ The <action> type attribute can be add,u
 
   <body>
     <release version="2.2" date="TBA">
+      <action dev="sebb" type="add" issue="IO-173" due-to="Marcos Vinícius da Silva">
+        FileUtils.listFiles() doesn't return directories
+      </action>        
       <action dev="sebb" type="fix" issue="IO-276" due-to="nkami">
         "FileUtils#deleteDirectoryOnExit(File)" does not work
       </action>        

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=1295700&r1=1295699&r2=1295700&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 Thu Mar  1 17:45:11 2012
@@ -415,14 +415,19 @@ public class FileUtils {
      * @param files the collection of files found.
      * @param directory the directory to search in.
      * @param filter the filter to apply to files and directories.
+     * @param includeSubDirectories indicates if will include the subdirectories themselves
      */
     private static void innerListFiles(Collection<File> files, File directory,
-            IOFileFilter filter) {
+            IOFileFilter filter, boolean includeSubDirectories) {
         File[] found = directory.listFiles((FileFilter) filter);
+        
         if (found != null) {
             for (File file : found) {
                 if (file.isDirectory()) {
-                    innerListFiles(files, file, filter);
+                    if (includeSubDirectories) {
+                        files.add(file);
+                    }
+                    innerListFiles(files, file, filter, includeSubDirectories);
                 } else {
                     files.add(file);
                 }
@@ -457,31 +462,76 @@ public class FileUtils {
      */
     public static Collection<File> listFiles(
             File directory, IOFileFilter fileFilter, IOFileFilter dirFilter) {
-        if (!directory.isDirectory()) {
-            throw new IllegalArgumentException(
-                    "Parameter 'directory' is not a directory");
-        }
-        if (fileFilter == null) {
-            throw new NullPointerException("Parameter 'fileFilter' is null");
-        }
+        validateListFilesParameters(directory, fileFilter);
+
+        IOFileFilter effFileFilter = setupEfectiveFileFilter(fileFilter);
+        IOFileFilter effDirFilter = setupEffectiveDirFilter(dirFilter);
 
-        //Setup effective file filter
-        IOFileFilter effFileFilter = FileFilterUtils.and(fileFilter,
-            FileFilterUtils.notFileFilter(DirectoryFileFilter.INSTANCE));
+        //Find files
+        Collection<File> files = new java.util.LinkedList<File>();
+        innerListFiles(files, directory,
+            FileFilterUtils.or(effFileFilter, effDirFilter), false);
+        return files;
+    }
+
+    private static void validateListFilesParameters(File directory,
+    		IOFileFilter fileFilter) {
+    	if (!directory.isDirectory()) {
+    		throw new IllegalArgumentException(
+    				"Parameter 'directory' is not a directory");
+    	}
+    	if (fileFilter == null) {
+    		throw new NullPointerException("Parameter 'fileFilter' is null");
+    	}
+    }
+
+    private static IOFileFilter setupEfectiveFileFilter(IOFileFilter fileFilter) {
+    	return FileFilterUtils.and(fileFilter,
+    			FileFilterUtils.notFileFilter(DirectoryFileFilter.INSTANCE));
+    }
 
-        //Setup effective directory filter
-        IOFileFilter effDirFilter;
+	private static IOFileFilter setupEffectiveDirFilter(IOFileFilter dirFilter) {
+		IOFileFilter effDirFilter;
         if (dirFilter == null) {
             effDirFilter = FalseFileFilter.INSTANCE;
         } else {
             effDirFilter = FileFilterUtils.and(dirFilter,
                 DirectoryFileFilter.INSTANCE);
         }
+        return effDirFilter;
+	}
+
+    /**
+     * Finds files within a given directory (and optionally its
+     * subdirectories). All files found are filtered by an IOFileFilter.
+     * <p>
+     * The resulting collection includes the subdirectories themselves.
+     * <p>
+     * @see org.apache.commons.io.FileUtils#listFiles  
+     *
+     * @param directory  the directory to search in
+     * @param fileFilter  filter to apply when finding files.
+     * @param dirFilter  optional filter to apply when finding subdirectories.
+     * If this parameter is <code>null</code>, subdirectories will not be included in the
+     * search. Use TrueFileFilter.INSTANCE to match all directories.
+     * @return an collection of java.io.File with the matching files
+     * @see org.apache.commons.io.filefilter.FileFilterUtils
+     * @see org.apache.commons.io.filefilter.NameFileFilter
+     */
+    public static Collection<File> listFilesAndDirs(
+            File directory, IOFileFilter fileFilter, IOFileFilter dirFilter) {
+        validateListFilesParameters(directory, fileFilter);
+
+        IOFileFilter effFileFilter = setupEfectiveFileFilter(fileFilter);
+        IOFileFilter effDirFilter = setupEffectiveDirFilter(dirFilter);
 
         //Find files
         Collection<File> files = new java.util.LinkedList<File>();
+        if (directory.isDirectory()) {
+            files.add(directory);
+        }
         innerListFiles(files, directory,
-            FileFilterUtils.or(effFileFilter, effDirFilter));
+            FileFilterUtils.or(effFileFilter, effDirFilter), true);
         return files;
     }
 
@@ -508,6 +558,30 @@ public class FileUtils {
         return listFiles(directory, fileFilter, dirFilter).iterator();
     }
 
+    /**
+     * Allows iteration over the files in given directory (and optionally
+     * its subdirectories).
+     * <p>
+     * All files found are filtered by an IOFileFilter. This method is
+     * based on {@link #listFilesAndDirs(File, IOFileFilter, IOFileFilter)},
+     * which supports Iterable ('foreach' loop).
+     * <p>
+     * The resulting iterator includes the subdirectories themselves.
+     * 
+     * @param directory  the directory to search in
+     * @param fileFilter  filter to apply when finding files.
+     * @param dirFilter  optional filter to apply when finding subdirectories.
+     * If this parameter is <code>null</code>, subdirectories will not be included in the
+     * search. Use TrueFileFilter.INSTANCE to match all directories.
+     * @return an iterator of java.io.File for the matching files
+     * @see org.apache.commons.io.filefilter.FileFilterUtils
+     * @see org.apache.commons.io.filefilter.NameFileFilter
+     */
+	public static Iterator<File> iterateFilesAndDirs(
+			File directory,	IOFileFilter fileFilter, IOFileFilter dirFilter) {
+		return listFilesAndDirs(directory, fileFilter, dirFilter).iterator();
+	}
+
     //-----------------------------------------------------------------------
     /**
      * Converts an array of file extensions to suffixes for use

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=1295700&r1=1295699&r2=1295700&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 Thu Mar  1 17:45:11 2012
@@ -1345,6 +1345,9 @@ public class FileUtilsTestCase extends F
         File subDir = new File(srcDir, "list_test" );
         subDir.mkdir();
 
+        File subDir2 = new File(subDir, "subdir" );
+        subDir2.mkdir();
+
         String[] fileNames = {"a.txt", "b.txt", "c.txt", "d.txt", "e.txt", "f.txt"};
         int[] fileSizes = {123, 234, 345, 456, 678, 789};
 
@@ -1360,7 +1363,7 @@ public class FileUtilsTestCase extends F
         int count = files.size();
         Object[] fileObjs = files.toArray();
 
-        assertEquals(files.size(), fileNames.length);
+        assertEquals(fileNames.length, files.size());
 
         Map<String, String> foundFileNames = new HashMap<String, String>();
 
@@ -1378,6 +1381,33 @@ public class FileUtilsTestCase extends F
 
         subDir.delete();
     }
+    
+    public void testListFilesWithDirs() throws IOException {
+    	File srcDir = getTestDirectory();
+    	
+    	File subDir1 = new File(srcDir, "subdir");
+    	subDir1.mkdir();
+    	
+    	File subDir2 = new File(subDir1, "subdir2");
+    	subDir2.mkdir();
+    	
+    	File someFile = new File(subDir2, "a.txt");
+    	createFile(someFile, 100);
+    	
+    	File subDir3 = new File(subDir2, "subdir3");
+    	subDir3.mkdir();
+    	
+    	Collection<File> files = FileUtils.listFilesAndDirs(subDir1, 
+    						new WildcardFileFilter("*.*"), new WildcardFileFilter("*"));
+    	
+    	assertEquals(4, files.size());
+    	assertTrue("Should contain the directory.", files.contains(subDir1));
+    	assertTrue("Should contain the directory.", files.contains(subDir2));
+    	assertTrue("Should contain the file.", files.contains(someFile));
+    	assertTrue("Should contain the directory.", files.contains(subDir3));
+    	
+    	subDir1.delete();
+    }
 
     public void testIterateFiles() throws Exception {
         File srcDir = getTestDirectory();
@@ -1414,6 +1444,36 @@ public class FileUtilsTestCase extends F
 
         subDir.delete();
     }
+    
+    public void testIterateFilesAndDirs() throws IOException {
+    	File srcDir = getTestDirectory();
+    	
+    	File subDir1 = new File(srcDir, "subdir");
+    	subDir1.mkdir();
+    	
+    	File subDir2 = new File(subDir1, "subdir2");
+    	subDir2.mkdir();
+    	
+    	File someFile = new File(subDir2, "a.txt");
+    	createFile(someFile, 100);
+    	
+    	File subDir3 = new File(subDir2, "subdir3");
+    	subDir3.mkdir();
+    	
+    	Collection<File> filesAndDirs = Arrays.asList(subDir1, subDir2, someFile, subDir3);
+    	
+    	int filesCount = 0;
+    	Iterator<File> files = FileUtils.iterateFilesAndDirs(subDir1, 
+                                                new WildcardFileFilter("*.*"),
+                                                new WildcardFileFilter("*"));
+        while (files.hasNext()) {
+            filesCount++;
+            File file = files.next();
+            assertTrue("Should contain the directory/file", filesAndDirs.contains(file));
+        }
+    	
+    	assertEquals(filesCount, filesAndDirs.size());
+    }
 
     public void testReadFileToStringWithDefaultEncoding() throws Exception {
         File file = new File(getTestDirectory(), "read.obj");