@@ -415,14 +415,19 @@ public static File[] convertFileCollectionToFileArray(Collection<File> files) {
415415 * @param files the collection of files found.
416416 * @param directory the directory to search in.
417417 * @param filter the filter to apply to files and directories.
418+ * @param includeSubDirectories indicates if will include the subdirectories themselves
418419 */
419420 private static void innerListFiles (Collection <File > files , File directory ,
420- IOFileFilter filter ) {
421+ IOFileFilter filter , boolean includeSubDirectories ) {
421422 File [] found = directory .listFiles ((FileFilter ) filter );
423+
422424 if (found != null ) {
423425 for (File file : found ) {
424426 if (file .isDirectory ()) {
425- innerListFiles (files , file , filter );
427+ if (includeSubDirectories ) {
428+ files .add (file );
429+ }
430+ innerListFiles (files , file , filter , includeSubDirectories );
426431 } else {
427432 files .add (file );
428433 }
@@ -457,31 +462,76 @@ private static void innerListFiles(Collection<File> files, File directory,
457462 */
458463 public static Collection <File > listFiles (
459464 File directory , IOFileFilter fileFilter , IOFileFilter dirFilter ) {
460- if (!directory .isDirectory ()) {
461- throw new IllegalArgumentException (
462- "Parameter 'directory' is not a directory" );
463- }
464- if (fileFilter == null ) {
465- throw new NullPointerException ("Parameter 'fileFilter' is null" );
466- }
465+ validateListFilesParameters (directory , fileFilter );
466+
467+ IOFileFilter effFileFilter = setupEfectiveFileFilter (fileFilter );
468+ IOFileFilter effDirFilter = setupEffectiveDirFilter (dirFilter );
469+
470+ //Find files
471+ Collection <File > files = new java .util .LinkedList <File >();
472+ innerListFiles (files , directory ,
473+ FileFilterUtils .or (effFileFilter , effDirFilter ), false );
474+ return files ;
475+ }
476+
477+ private static void validateListFilesParameters (File directory ,
478+ IOFileFilter fileFilter ) {
479+ if (!directory .isDirectory ()) {
480+ throw new IllegalArgumentException (
481+ "Parameter 'directory' is not a directory" );
482+ }
483+ if (fileFilter == null ) {
484+ throw new NullPointerException ("Parameter 'fileFilter' is null" );
485+ }
486+ }
467487
468- //Setup effective file filter
469- IOFileFilter effFileFilter = FileFilterUtils .and (fileFilter ,
470- FileFilterUtils .notFileFilter (DirectoryFileFilter .INSTANCE ));
488+ private static IOFileFilter setupEfectiveFileFilter (IOFileFilter fileFilter ) {
489+ return FileFilterUtils .and (fileFilter ,
490+ FileFilterUtils .notFileFilter (DirectoryFileFilter .INSTANCE ));
491+ }
471492
472- //Setup effective directory filter
473- IOFileFilter effDirFilter ;
493+ private static IOFileFilter setupEffectiveDirFilter ( IOFileFilter dirFilter ) {
494+ IOFileFilter effDirFilter ;
474495 if (dirFilter == null ) {
475496 effDirFilter = FalseFileFilter .INSTANCE ;
476497 } else {
477498 effDirFilter = FileFilterUtils .and (dirFilter ,
478499 DirectoryFileFilter .INSTANCE );
479500 }
501+ return effDirFilter ;
502+ }
503+
504+ /**
505+ * Finds files within a given directory (and optionally its
506+ * subdirectories). All files found are filtered by an IOFileFilter.
507+ * <p>
508+ * The resulting collection includes the subdirectories themselves.
509+ * <p>
510+ * @see org.apache.commons.io.FileUtils#listFiles
511+ *
512+ * @param directory the directory to search in
513+ * @param fileFilter filter to apply when finding files.
514+ * @param dirFilter optional filter to apply when finding subdirectories.
515+ * If this parameter is <code>null</code>, subdirectories will not be included in the
516+ * search. Use TrueFileFilter.INSTANCE to match all directories.
517+ * @return an collection of java.io.File with the matching files
518+ * @see org.apache.commons.io.filefilter.FileFilterUtils
519+ * @see org.apache.commons.io.filefilter.NameFileFilter
520+ */
521+ public static Collection <File > listFilesAndDirs (
522+ File directory , IOFileFilter fileFilter , IOFileFilter dirFilter ) {
523+ validateListFilesParameters (directory , fileFilter );
524+
525+ IOFileFilter effFileFilter = setupEfectiveFileFilter (fileFilter );
526+ IOFileFilter effDirFilter = setupEffectiveDirFilter (dirFilter );
480527
481528 //Find files
482529 Collection <File > files = new java .util .LinkedList <File >();
530+ if (directory .isDirectory ()) {
531+ files .add (directory );
532+ }
483533 innerListFiles (files , directory ,
484- FileFilterUtils .or (effFileFilter , effDirFilter ));
534+ FileFilterUtils .or (effFileFilter , effDirFilter ), true );
485535 return files ;
486536 }
487537
@@ -508,6 +558,30 @@ public static Iterator<File> iterateFiles(
508558 return listFiles (directory , fileFilter , dirFilter ).iterator ();
509559 }
510560
561+ /**
562+ * Allows iteration over the files in given directory (and optionally
563+ * its subdirectories).
564+ * <p>
565+ * All files found are filtered by an IOFileFilter. This method is
566+ * based on {@link #listFilesAndDirs(File, IOFileFilter, IOFileFilter)},
567+ * which supports Iterable ('foreach' loop).
568+ * <p>
569+ * The resulting iterator includes the subdirectories themselves.
570+ *
571+ * @param directory the directory to search in
572+ * @param fileFilter filter to apply when finding files.
573+ * @param dirFilter optional filter to apply when finding subdirectories.
574+ * If this parameter is <code>null</code>, subdirectories will not be included in the
575+ * search. Use TrueFileFilter.INSTANCE to match all directories.
576+ * @return an iterator of java.io.File for the matching files
577+ * @see org.apache.commons.io.filefilter.FileFilterUtils
578+ * @see org.apache.commons.io.filefilter.NameFileFilter
579+ */
580+ public static Iterator <File > iterateFilesAndDirs (
581+ File directory , IOFileFilter fileFilter , IOFileFilter dirFilter ) {
582+ return listFilesAndDirs (directory , fileFilter , dirFilter ).iterator ();
583+ }
584+
511585 //-----------------------------------------------------------------------
512586 /**
513587 * Converts an array of file extensions to suffixes for use
0 commit comments