View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io.filefilter;
18  
19  import java.io.File;
20  import java.io.FileFilter;
21  import java.io.FilenameFilter;
22  import java.util.Arrays;
23  import java.util.Collections;
24  import java.util.Date;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.Objects;
28  import java.util.Set;
29  import java.util.stream.Collector;
30  import java.util.stream.Collectors;
31  import java.util.stream.Stream;
32  import java.util.stream.StreamSupport;
33  
34  import org.apache.commons.io.FileUtils;
35  import org.apache.commons.io.IOCase;
36  
37  /**
38   * Useful utilities for working with file filters. It provides access to most
39   * file filter implementations in this package so you don't have to import
40   * every class you use.
41   *
42   * @since 1.0
43   */
44  public class FileFilterUtils {
45  
46      /* Constructed on demand and then cached */
47      private static final IOFileFilter CVS_FILTER = notFileFilter(
48              and(directoryFileFilter(), nameFileFilter("CVS")));
49  
50      /* Constructed on demand and then cached */
51      private static final IOFileFilter SVN_FILTER = notFileFilter(
52              and(directoryFileFilter(), nameFileFilter(".svn")));
53  
54      /**
55       * Returns a filter that returns true if the file was last modified before
56       * or at the specified cutoff date.
57       *
58       * @param cutoffDate  the time threshold
59       * @return an appropriately configured age file filter
60       * @see AgeFileFilter
61       * @since 1.2
62       */
63      public static IOFileFilter ageFileFilter(final Date cutoffDate) {
64          return new AgeFileFilter(cutoffDate);
65      }
66  
67      /**
68       * Returns a filter that filters files based on a cutoff date.
69       *
70       * @param cutoffDate  the time threshold
71       * @param acceptOlder  if true, older files get accepted, if false, newer
72       * @return an appropriately configured age file filter
73       * @see AgeFileFilter
74       * @since 1.2
75       */
76      public static IOFileFilter ageFileFilter(final Date cutoffDate, final boolean acceptOlder) {
77          return new AgeFileFilter(cutoffDate, acceptOlder);
78      }
79  
80      /**
81       * Returns a filter that returns true if the file was last modified before
82       * or at the same time as the specified reference file.
83       *
84       * @param cutoffReference  the file whose last modification
85       *        time is used as the threshold age of the files
86       * @return an appropriately configured age file filter
87       * @see AgeFileFilter
88       * @since 1.2
89       */
90      public static IOFileFilter ageFileFilter(final File cutoffReference) {
91          return new AgeFileFilter(cutoffReference);
92      }
93  
94      /**
95       * Returns a filter that filters files based on a cutoff reference file.
96       *
97       * @param cutoffReference  the file whose last modification
98       *        time is used as the threshold age of the files
99       * @param acceptOlder  if true, older files get accepted, if false, newer
100      * @return an appropriately configured age file filter
101      * @see AgeFileFilter
102      * @since 1.2
103      */
104     public static IOFileFilter ageFileFilter(final File cutoffReference, final boolean acceptOlder) {
105         return new AgeFileFilter(cutoffReference, acceptOlder);
106     }
107 
108     /**
109      * Returns a filter that returns true if the file was last modified before
110      * or at the specified cutoff time.
111      *
112      * @param cutoffMillis  the time threshold
113      * @return an appropriately configured age file filter
114      * @see AgeFileFilter
115      * @since 1.2
116      */
117     public static IOFileFilter ageFileFilter(final long cutoffMillis) {
118         return new AgeFileFilter(cutoffMillis);
119     }
120 
121     /**
122      * Returns a filter that filters files based on a cutoff time.
123      *
124      * @param cutoffMillis  the time threshold
125      * @param acceptOlder  if true, older files get accepted, if false, newer
126      * @return an appropriately configured age file filter
127      * @see AgeFileFilter
128      * @since 1.2
129      */
130     public static IOFileFilter ageFileFilter(final long cutoffMillis, final boolean acceptOlder) {
131         return new AgeFileFilter(cutoffMillis, acceptOlder);
132     }
133 
134     /**
135      * Returns a filter that ANDs the specified filters.
136      *
137      * @param filters the IOFileFilters that will be ANDed together.
138      * @return a filter that ANDs the specified filters
139      *
140      * @throws IllegalArgumentException if the filters are null or contain a
141      *         null value.
142      * @see AndFileFilter
143      * @since 2.0
144      */
145     public static IOFileFilter and(final IOFileFilter... filters) {
146         return new AndFileFilter(toList(filters));
147     }
148 
149     /**
150      * Returns a filter that ANDs the two specified filters.
151      *
152      * @param filter1  the first filter
153      * @param filter2  the second filter
154      * @return a filter that ANDs the two specified filters
155      * @see #and(IOFileFilter...)
156      * @see AndFileFilter
157      * @deprecated use {@link #and(IOFileFilter...)}
158      */
159     @Deprecated
160     public static IOFileFilter andFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) {
161         return new AndFileFilter(filter1, filter2);
162     }
163 
164     /**
165      * Returns an {@link IOFileFilter} that wraps the
166      * {@link FileFilter} instance.
167      *
168      * @param filter  the filter to be wrapped
169      * @return a new filter that implements IOFileFilter
170      * @see DelegateFileFilter
171      */
172     public static IOFileFilter asFileFilter(final FileFilter filter) {
173         return new DelegateFileFilter(filter);
174     }
175 
176     /**
177      * Returns an {@link IOFileFilter} that wraps the
178      * {@link FilenameFilter} instance.
179      *
180      * @param filter  the filter to be wrapped
181      * @return a new filter that implements IOFileFilter
182      * @see DelegateFileFilter
183      */
184     public static IOFileFilter asFileFilter(final FilenameFilter filter) {
185         return new DelegateFileFilter(filter);
186     }
187 
188     /**
189      * Returns a filter that checks if the file is a directory.
190      *
191      * @return file filter that accepts only directories and not files
192      * @see DirectoryFileFilter#DIRECTORY
193      */
194     public static IOFileFilter directoryFileFilter() {
195         return DirectoryFileFilter.DIRECTORY;
196     }
197 
198     /**
199      * Returns a filter that always returns false.
200      *
201      * @return a false filter
202      * @see FalseFileFilter#FALSE
203      */
204     public static IOFileFilter falseFileFilter() {
205         return FalseFileFilter.FALSE;
206     }
207 
208     /**
209      * Returns a filter that checks if the file is a file (and not a directory).
210      *
211      * @return file filter that accepts only files and not directories
212      * @see FileFileFilter#INSTANCE
213      */
214     public static IOFileFilter fileFileFilter() {
215         return FileFileFilter.INSTANCE;
216     }
217 
218     /**
219      * <p>
220      * Applies an {@link IOFileFilter} to the provided {@link File}
221      * objects. The resulting array is a subset of the original file list that
222      * matches the provided filter.
223      * </p>
224      *
225      * <pre>
226      * Set&lt;File&gt; allFiles = ...
227      * Set&lt;File&gt; javaFiles = FileFilterUtils.filterSet(allFiles,
228      *     FileFilterUtils.suffixFileFilter(".java"));
229      * </pre>
230      * @param filter the filter to apply to the set of files.
231      * @param files the array of files to apply the filter to.
232      *
233      * @return a subset of {@code files} that is accepted by the
234      *         file filter.
235      * @throws NullPointerException if the filter is {@code null}
236      *         or {@code files} contains a {@code null} value.
237      *
238      * @since 2.0
239      */
240     public static File[] filter(final IOFileFilter filter, final File... files) {
241         Objects.requireNonNull(filter, "filter");
242         if (files == null) {
243             return FileUtils.EMPTY_FILE_ARRAY;
244         }
245         return filterFiles(filter, Stream.of(files), Collectors.toList()).toArray(FileUtils.EMPTY_FILE_ARRAY);
246     }
247 
248     /**
249      * <p>
250      * Applies an {@link IOFileFilter} to the provided {@link File}
251      * objects. The resulting array is a subset of the original file list that
252      * matches the provided filter.
253      * </p>
254      *
255      * <p>
256      * The {@link Set} returned by this method is not guaranteed to be thread safe.
257      * </p>
258      *
259      * <pre>
260      * Set&lt;File&gt; allFiles = ...
261      * Set&lt;File&gt; javaFiles = FileFilterUtils.filterSet(allFiles,
262      *     FileFilterUtils.suffixFileFilter(".java"));
263      * </pre>
264      * @param filter the filter to apply to the set of files.
265      * @param files the array of files to apply the filter to.
266      *
267      * @return a subset of {@code files} that is accepted by the
268      *         file filter.
269      * @throws IllegalArgumentException if the filter is {@code null}
270      *         or {@code files} contains a {@code null} value.
271      *
272      * @since 2.0
273      */
274     public static File[] filter(final IOFileFilter filter, final Iterable<File> files) {
275         return filterList(filter, files).toArray(FileUtils.EMPTY_FILE_ARRAY);
276     }
277 
278     /**
279      * <p>
280      * Applies an {@link IOFileFilter} to the provided {@link File} stream and collects the accepted files.
281      * </p>
282      *
283      * @param filter the filter to apply to the stream of files.
284      * @param stream the stream of files on which to apply the filter.
285      * @param collector how to collect the end result.
286      *
287      * @param <R> the return type.
288      * @param <A> the mutable accumulation type of the reduction operation (often hidden as an implementation detail)
289      * @return a subset of files from the stream that is accepted by the filter.
290      * @throws NullPointerException if the filter is {@code null}.
291      */
292     private static <R, A> R filterFiles(final IOFileFilter filter, final Stream<File> stream,
293         final Collector<? super File, A, R> collector) {
294         Objects.requireNonNull(filter, "filter");
295         Objects.requireNonNull(collector, "collector");
296         if (stream == null) {
297             return Stream.<File>empty().collect(collector);
298         }
299         return stream.filter(filter::accept).collect(collector);
300     }
301 
302     /**
303      * <p>
304      * Applies an {@link IOFileFilter} to the provided {@link File}
305      * objects. The resulting list is a subset of the original files that
306      * matches the provided filter.
307      * </p>
308      *
309      * <p>
310      * The {@link List} returned by this method is not guaranteed to be thread safe.
311      * </p>
312      *
313      * <pre>
314      * List&lt;File&gt; filesAndDirectories = ...
315      * List&lt;File&gt; directories = FileFilterUtils.filterList(filesAndDirectories,
316      *     FileFilterUtils.directoryFileFilter());
317      * </pre>
318      * @param filter the filter to apply to each files in the list.
319      * @param files the collection of files to apply the filter to.
320      *
321      * @return a subset of {@code files} that is accepted by the
322      *         file filter.
323      * @throws IllegalArgumentException if the filter is {@code null}
324      *         or {@code files} contains a {@code null} value.
325      * @since 2.0
326      */
327     public static List<File> filterList(final IOFileFilter filter, final File... files) {
328         return Arrays.asList(filter(filter, files));
329     }
330 
331     /**
332      * <p>
333      * Applies an {@link IOFileFilter} to the provided {@link File}
334      * objects. The resulting list is a subset of the original files that
335      * matches the provided filter.
336      * </p>
337      *
338      * <p>
339      * The {@link List} returned by this method is not guaranteed to be thread safe.
340      * </p>
341      *
342      * <pre>
343      * List&lt;File&gt; filesAndDirectories = ...
344      * List&lt;File&gt; directories = FileFilterUtils.filterList(filesAndDirectories,
345      *     FileFilterUtils.directoryFileFilter());
346      * </pre>
347      * @param filter the filter to apply to each files in the list.
348      * @param files the collection of files to apply the filter to.
349      *
350      * @return a subset of {@code files} that is accepted by the
351      *         file filter.
352      * @throws IllegalArgumentException if the filter is {@code null}
353      * @since 2.0
354      */
355     public static List<File> filterList(final IOFileFilter filter, final Iterable<File> files) {
356         if (files == null) {
357             return Collections.emptyList();
358         }
359         return filterFiles(filter, StreamSupport.stream(files.spliterator(), false), Collectors.toList());
360     }
361 
362     /**
363      * <p>
364      * Applies an {@link IOFileFilter} to the provided {@link File}
365      * objects. The resulting set is a subset of the original file list that
366      * matches the provided filter.
367      * </p>
368      *
369      * <p>
370      * The {@link Set} returned by this method is not guaranteed to be thread safe.
371      * </p>
372      *
373      * <pre>
374      * Set&lt;File&gt; allFiles = ...
375      * Set&lt;File&gt; javaFiles = FileFilterUtils.filterSet(allFiles,
376      *     FileFilterUtils.suffixFileFilter(".java"));
377      * </pre>
378      * @param filter the filter to apply to the set of files.
379      * @param files the collection of files to apply the filter to.
380      *
381      * @return a subset of {@code files} that is accepted by the
382      *         file filter.
383      * @throws IllegalArgumentException if the filter is {@code null}
384      *         or {@code files} contains a {@code null} value.
385      *
386      * @since 2.0
387      */
388     public static Set<File> filterSet(final IOFileFilter filter, final File... files) {
389         return new HashSet<>(Arrays.asList(filter(filter, files)));
390     }
391 
392     /**
393      * <p>
394      * Applies an {@link IOFileFilter} to the provided {@link File}
395      * objects. The resulting set is a subset of the original file list that
396      * matches the provided filter.
397      * </p>
398      *
399      * <p>
400      * The {@link Set} returned by this method is not guaranteed to be thread safe.
401      * </p>
402      *
403      * <pre>
404      * Set&lt;File&gt; allFiles = ...
405      * Set&lt;File&gt; javaFiles = FileFilterUtils.filterSet(allFiles,
406      *     FileFilterUtils.suffixFileFilter(".java"));
407      * </pre>
408      * @param filter the filter to apply to the set of files.
409      * @param files the collection of files to apply the filter to.
410      *
411      * @return a subset of {@code files} that is accepted by the
412      *         file filter.
413      * @throws IllegalArgumentException if the filter is {@code null}
414      *
415      * @since 2.0
416      */
417     public static Set<File> filterSet(final IOFileFilter filter, final Iterable<File> files) {
418         if (files == null) {
419             return Collections.emptySet();
420         }
421         return filterFiles(filter, StreamSupport.stream(files.spliterator(), false), Collectors.toSet());
422     }
423 
424     /**
425      * Returns a filter that accepts files that begin with the provided magic
426      * number.
427      *
428      * @param magicNumber the magic number (byte sequence) to match at the
429      *        beginning of each file.
430      *
431      * @return an IOFileFilter that accepts files beginning with the provided
432      *         magic number.
433      *
434      * @throws IllegalArgumentException if {@code magicNumber} is
435      *         {@code null} or is of length zero.
436      * @see MagicNumberFileFilter
437      * @since 2.0
438      */
439     public static IOFileFilter magicNumberFileFilter(final byte[] magicNumber) {
440         return new MagicNumberFileFilter(magicNumber);
441     }
442 
443     /**
444      * Returns a filter that accepts files that contains the provided magic
445      * number at a specified offset within the file.
446      *
447      * @param magicNumber the magic number (byte sequence) to match at the
448      *        provided offset in each file.
449      * @param offset the offset within the files to look for the magic number.
450      *
451      * @return an IOFileFilter that accepts files containing the magic number
452      *         at the specified offset.
453      *
454      * @throws IllegalArgumentException if {@code magicNumber} is
455      *         {@code null}, or contains no bytes, or {@code offset}
456      *         is a negative number.
457      * @see MagicNumberFileFilter
458      * @since 2.0
459      */
460     public static IOFileFilter magicNumberFileFilter(final byte[] magicNumber, final long offset) {
461         return new MagicNumberFileFilter(magicNumber, offset);
462     }
463 
464     /**
465      * Returns a filter that accepts files that begin with the provided magic
466      * number.
467      *
468      * @param magicNumber the magic number (byte sequence) to match at the
469      *        beginning of each file.
470      *
471      * @return an IOFileFilter that accepts files beginning with the provided
472      *         magic number.
473      *
474      * @throws IllegalArgumentException if {@code magicNumber} is
475      *         {@code null} or the empty String.
476      * @see MagicNumberFileFilter
477      * @since 2.0
478      */
479     public static IOFileFilter magicNumberFileFilter(final String magicNumber) {
480         return new MagicNumberFileFilter(magicNumber);
481     }
482 
483     /**
484      * Returns a filter that accepts files that contains the provided magic
485      * number at a specified offset within the file.
486      *
487      * @param magicNumber the magic number (byte sequence) to match at the
488      *        provided offset in each file.
489      * @param offset the offset within the files to look for the magic number.
490      *
491      * @return an IOFileFilter that accepts files containing the magic number
492      *         at the specified offset.
493      *
494      * @throws IllegalArgumentException if {@code magicNumber} is
495      *         {@code null} or the empty String, or if offset is a
496      *         negative number.
497      * @see MagicNumberFileFilter
498      * @since 2.0
499      */
500     public static IOFileFilter magicNumberFileFilter(final String magicNumber, final long offset) {
501         return new MagicNumberFileFilter(magicNumber, offset);
502     }
503 
504     /**
505      * Decorates a filter to make it ignore CVS directories.
506      * Passing in {@code null} will return a filter that accepts everything
507      * except CVS directories.
508      *
509      * @param filter  the filter to decorate, null means an unrestricted filter
510      * @return the decorated filter, never null
511      * @since 1.1 (method existed but had a bug in 1.0)
512      */
513     public static IOFileFilter makeCVSAware(final IOFileFilter filter) {
514         return filter == null ? CVS_FILTER : and(filter, CVS_FILTER);
515     }
516 
517     /**
518      * Decorates a filter so that it only applies to directories and not to files.
519      *
520      * @param filter  the filter to decorate, null means an unrestricted filter
521      * @return the decorated filter, never null
522      * @see DirectoryFileFilter#DIRECTORY
523      * @since 1.3
524      */
525     public static IOFileFilter makeDirectoryOnly(final IOFileFilter filter) {
526         if (filter == null) {
527             return DirectoryFileFilter.DIRECTORY;
528         }
529         return DirectoryFileFilter.DIRECTORY.and(filter);
530     }
531 
532     /**
533      * Decorates a filter so that it only applies to files and not to directories.
534      *
535      * @param filter  the filter to decorate, null means an unrestricted filter
536      * @return the decorated filter, never null
537      * @see FileFileFilter#INSTANCE
538      * @since 1.3
539      */
540     public static IOFileFilter makeFileOnly(final IOFileFilter filter) {
541         if (filter == null) {
542             return FileFileFilter.INSTANCE;
543         }
544         return FileFileFilter.INSTANCE.and(filter);
545     }
546 
547     /**
548      * Decorates a filter to make it ignore SVN directories.
549      * Passing in {@code null} will return a filter that accepts everything
550      * except SVN directories.
551      *
552      * @param filter  the filter to decorate, null means an unrestricted filter
553      * @return the decorated filter, never null
554      * @since 1.1
555      */
556     public static IOFileFilter makeSVNAware(final IOFileFilter filter) {
557         return filter == null ? SVN_FILTER : and(filter, SVN_FILTER);
558     }
559 
560     /**
561      * Returns a filter that returns true if the file name matches the specified text.
562      *
563      * @param name  the file name
564      * @return a name checking filter
565      * @see NameFileFilter
566      */
567     public static IOFileFilter nameFileFilter(final String name) {
568         return new NameFileFilter(name);
569     }
570 
571     /**
572      * Returns a filter that returns true if the file name matches the specified text.
573      *
574      * @param name  the file name
575      * @param ioCase  how to handle case sensitivity, null means case-sensitive
576      * @return a name checking filter
577      * @see NameFileFilter
578      * @since 2.0
579      */
580     public static IOFileFilter nameFileFilter(final String name, final IOCase ioCase) {
581         return new NameFileFilter(name, ioCase);
582     }
583 
584     /**
585      * Returns a filter that NOTs the specified filter.
586      *
587      * @param filter  the filter to invert
588      * @return a filter that NOTs the specified filter
589      * @see NotFileFilter
590      */
591     public static IOFileFilter notFileFilter(final IOFileFilter filter) {
592         return filter.negate();
593     }
594 
595     /**
596      * Returns a filter that ORs the specified filters.
597      *
598      * @param filters the IOFileFilters that will be ORed together.
599      * @return a filter that ORs the specified filters
600      *
601      * @throws IllegalArgumentException if the filters are null or contain a
602      *         null value.
603      * @see OrFileFilter
604      * @since 2.0
605      */
606     public static IOFileFilter or(final IOFileFilter... filters) {
607         return new OrFileFilter(toList(filters));
608     }
609 
610     /**
611      * Returns a filter that ORs the two specified filters.
612      *
613      * @param filter1  the first filter
614      * @param filter2  the second filter
615      * @return a filter that ORs the two specified filters
616      * @see #or(IOFileFilter...)
617      * @see OrFileFilter
618      * @deprecated use {@link #or(IOFileFilter...)}
619      */
620     @Deprecated
621     public static IOFileFilter orFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) {
622         return new OrFileFilter(filter1, filter2);
623     }
624 
625     /**
626      * Returns a filter that returns true if the file name starts with the specified text.
627      *
628      * @param prefix  the file name prefix
629      * @return a prefix checking filter
630      * @see PrefixFileFilter
631      */
632     public static IOFileFilter prefixFileFilter(final String prefix) {
633         return new PrefixFileFilter(prefix);
634     }
635 
636     /**
637      * Returns a filter that returns true if the file name starts with the specified text.
638      *
639      * @param prefix  the file name prefix
640      * @param ioCase  how to handle case sensitivity, null means case-sensitive
641      * @return a prefix checking filter
642      * @see PrefixFileFilter
643      * @since 2.0
644      */
645     public static IOFileFilter prefixFileFilter(final String prefix, final IOCase ioCase) {
646         return new PrefixFileFilter(prefix, ioCase);
647     }
648 
649     /**
650      * Returns a filter that returns true if the file is bigger than a certain size.
651      *
652      * @param threshold  the file size threshold
653      * @return an appropriately configured SizeFileFilter
654      * @see SizeFileFilter
655      * @since 1.2
656      */
657     public static IOFileFilter sizeFileFilter(final long threshold) {
658         return new SizeFileFilter(threshold);
659     }
660 
661     /**
662      * Returns a filter that filters based on file size.
663      *
664      * @param threshold  the file size threshold
665      * @param acceptLarger  if true, larger files get accepted, if false, smaller
666      * @return an appropriately configured SizeFileFilter
667      * @see SizeFileFilter
668      * @since 1.2
669      */
670     public static IOFileFilter sizeFileFilter(final long threshold, final boolean acceptLarger) {
671         return new SizeFileFilter(threshold, acceptLarger);
672     }
673 
674     /**
675      * Returns a filter that accepts files whose size is &gt;= minimum size
676      * and &lt;= maximum size.
677      *
678      * @param minSizeInclusive the minimum file size (inclusive)
679      * @param maxSizeInclusive the maximum file size (inclusive)
680      * @return an appropriately configured IOFileFilter
681      * @see SizeFileFilter
682      * @since 1.3
683      */
684     public static IOFileFilter sizeRangeFileFilter(final long minSizeInclusive, final long maxSizeInclusive ) {
685         final IOFileFilter minimumFilter = new SizeFileFilter(minSizeInclusive, true);
686         final IOFileFilter maximumFilter = new SizeFileFilter(maxSizeInclusive + 1L, false);
687         return minimumFilter.and(maximumFilter);
688     }
689 
690     /**
691      * Returns a filter that returns true if the file name ends with the specified text.
692      *
693      * @param suffix  the file name suffix
694      * @return a suffix checking filter
695      * @see SuffixFileFilter
696      */
697     public static IOFileFilter suffixFileFilter(final String suffix) {
698         return new SuffixFileFilter(suffix);
699     }
700 
701     /**
702      * Returns a filter that returns true if the file name ends with the specified text.
703      *
704      * @param suffix  the file name suffix
705      * @param ioCase  how to handle case sensitivity, null means case-sensitive
706      * @return a suffix checking filter
707      * @see SuffixFileFilter
708      * @since 2.0
709      */
710     public static IOFileFilter suffixFileFilter(final String suffix, final IOCase ioCase) {
711         return new SuffixFileFilter(suffix, ioCase);
712     }
713 
714     /**
715      * Create a List of file filters.
716      *
717      * @param filters The file filters
718      * @return The list of file filters
719      * @throws NullPointerException if the filters are null or contain a
720      *         null value.
721      * @since 2.0
722      */
723     public static List<IOFileFilter> toList(final IOFileFilter... filters) {
724         return Stream.of(Objects.requireNonNull(filters, "filters")).map(Objects::requireNonNull).collect(Collectors.toList());
725     }
726 
727     /**
728      * Returns a filter that always returns true.
729      *
730      * @return a true filter
731      * @see TrueFileFilter#TRUE
732      */
733     public static IOFileFilter trueFileFilter() {
734         return TrueFileFilter.TRUE;
735     }
736 
737     /**
738      * FileFilterUtils is not normally instantiated.
739      */
740     public FileFilterUtils() {
741     }
742 
743 }