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    *      https://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      * @throws IllegalArgumentException if the filters are null or contain a
140      *         null value.
141      * @see AndFileFilter
142      * @since 2.0
143      */
144     public static IOFileFilter and(final IOFileFilter... filters) {
145         return new AndFileFilter(toList(filters));
146     }
147 
148     /**
149      * Returns a filter that ANDs the two specified filters.
150      *
151      * @param filter1  the first filter.
152      * @param filter2  the second filter.
153      * @return a filter that ANDs the two specified filters.
154      * @see #and(IOFileFilter...)
155      * @see AndFileFilter
156      * @deprecated Use {@link #and(IOFileFilter...)}
157      */
158     @Deprecated
159     public static IOFileFilter andFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) {
160         return new AndFileFilter(filter1, filter2);
161     }
162 
163     /**
164      * Returns an {@link IOFileFilter} that wraps the
165      * {@link FileFilter} instance.
166      *
167      * @param filter  the filter to be wrapped.
168      * @return a new filter that implements IOFileFilter.
169      * @see DelegateFileFilter
170      */
171     public static IOFileFilter asFileFilter(final FileFilter filter) {
172         return new DelegateFileFilter(filter);
173     }
174 
175     /**
176      * Returns an {@link IOFileFilter} that wraps the
177      * {@link FilenameFilter} instance.
178      *
179      * @param filter  the filter to be wrapped.
180      * @return a new filter that implements IOFileFilter.
181      * @see DelegateFileFilter
182      */
183     public static IOFileFilter asFileFilter(final FilenameFilter filter) {
184         return new DelegateFileFilter(filter);
185     }
186 
187     /**
188      * Returns a filter that checks if the file is a directory.
189      *
190      * @return file filter that accepts only directories and not files.
191      * @see DirectoryFileFilter#DIRECTORY
192      */
193     public static IOFileFilter directoryFileFilter() {
194         return DirectoryFileFilter.DIRECTORY;
195     }
196 
197     /**
198      * Returns a filter that always returns false.
199      *
200      * @return a false filter.
201      * @see FalseFileFilter#FALSE
202      */
203     public static IOFileFilter falseFileFilter() {
204         return FalseFileFilter.FALSE;
205     }
206 
207     /**
208      * Returns a filter that checks if the file is a file (and not a directory).
209      *
210      * @return file filter that accepts only files and not directories.
211      * @see FileFileFilter#INSTANCE
212      */
213     public static IOFileFilter fileFileFilter() {
214         return FileFileFilter.INSTANCE;
215     }
216 
217     /**
218      * <p>
219      * Applies an {@link IOFileFilter} to the provided {@link File}
220      * objects. The resulting array is a subset of the original file list that
221      * matches the provided filter.
222      * </p>
223      *
224      * <pre>
225      * Set&lt;File&gt; allFiles = ...
226      * Set&lt;File&gt; javaFiles = FileFilterUtils.filterSet(allFiles,
227      *     FileFilterUtils.suffixFileFilter(".java"));
228      * </pre>
229      *
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      * @return a subset of {@code files} that is accepted by the
233      *         file filter.
234      * @throws NullPointerException if the filter is {@code null}
235      *         or {@code files} contains a {@code null} value.
236      * @since 2.0
237      */
238     public static File[] filter(final IOFileFilter filter, final File... files) {
239         Objects.requireNonNull(filter, "filter");
240         if (files == null) {
241             return FileUtils.EMPTY_FILE_ARRAY;
242         }
243         return filterFiles(filter, Stream.of(files), Collectors.toList()).toArray(FileUtils.EMPTY_FILE_ARRAY);
244     }
245 
246     /**
247      * <p>
248      * Applies an {@link IOFileFilter} to the provided {@link File}
249      * objects. The resulting array is a subset of the original file list that
250      * matches the provided filter.
251      * </p>
252      *
253      * <p>
254      * The {@link Set} returned by this method is not guaranteed to be thread safe.
255      * </p>
256      *
257      * <pre>
258      * Set&lt;File&gt; allFiles = ...
259      * Set&lt;File&gt; javaFiles = FileFilterUtils.filterSet(allFiles,
260      *     FileFilterUtils.suffixFileFilter(".java"));
261      * </pre>
262      *
263      * @param filter the filter to apply to the set of files.
264      * @param files the array of files to apply the filter to.
265      * @return a subset of {@code files} that is accepted by the
266      *         file filter.
267      * @throws IllegalArgumentException if the filter is {@code null}
268      *         or {@code files} contains a {@code null} value.
269      * @since 2.0
270      */
271     public static File[] filter(final IOFileFilter filter, final Iterable<File> files) {
272         return filterList(filter, files).toArray(FileUtils.EMPTY_FILE_ARRAY);
273     }
274 
275     /**
276      * <p>
277      * Applies an {@link IOFileFilter} to the provided {@link File} stream and collects the accepted files.
278      * </p>
279      *
280      * @param filter the filter to apply to the stream of files.
281      * @param stream the stream of files on which to apply the filter.
282      * @param collector how to collect the end result.
283      * @param <R> the return type.
284      * @param <A> the mutable accumulation type of the reduction operation (often hidden as an implementation detail).
285      * @return a subset of files from the stream that is accepted by the filter.
286      * @throws NullPointerException if the filter is {@code null}.
287      */
288     private static <R, A> R filterFiles(final IOFileFilter filter, final Stream<File> stream,
289         final Collector<? super File, A, R> collector) {
290         Objects.requireNonNull(filter, "filter");
291         Objects.requireNonNull(collector, "collector");
292         if (stream == null) {
293             return Stream.<File>empty().collect(collector);
294         }
295         return stream.filter(filter::accept).collect(collector);
296     }
297 
298     /**
299      * <p>
300      * Applies an {@link IOFileFilter} to the provided {@link File}
301      * objects. The resulting list is a subset of the original files that
302      * matches the provided filter.
303      * </p>
304      *
305      * <p>
306      * The {@link List} returned by this method is not guaranteed to be thread safe.
307      * </p>
308      *
309      * <pre>
310      * List&lt;File&gt; filesAndDirectories = ...
311      * List&lt;File&gt; directories = FileFilterUtils.filterList(filesAndDirectories,
312      *     FileFilterUtils.directoryFileFilter());
313      * </pre>
314      *
315      * @param filter the filter to apply to each files in the list.
316      * @param files the collection of files to apply the filter to.
317      * @return a subset of {@code files} that is accepted by the
318      *         file filter.
319      * @throws IllegalArgumentException if the filter is {@code null}
320      *         or {@code files} contains a {@code null} value.
321      * @since 2.0
322      */
323     public static List<File> filterList(final IOFileFilter filter, final File... files) {
324         return Arrays.asList(filter(filter, files));
325     }
326 
327     /**
328      * <p>
329      * Applies an {@link IOFileFilter} to the provided {@link File}
330      * objects. The resulting list is a subset of the original files that
331      * matches the provided filter.
332      * </p>
333      *
334      * <p>
335      * The {@link List} returned by this method is not guaranteed to be thread safe.
336      * </p>
337      *
338      * <pre>
339      * List&lt;File&gt; filesAndDirectories = ...
340      * List&lt;File&gt; directories = FileFilterUtils.filterList(filesAndDirectories,
341      *     FileFilterUtils.directoryFileFilter());
342      * </pre>
343      *
344      * @param filter the filter to apply to each files in the list.
345      * @param files the collection of files to apply the filter to.
346      * @return a subset of {@code files} that is accepted by the
347      *         file filter.
348      * @throws IllegalArgumentException if the filter is {@code null}
349      * @since 2.0
350      */
351     public static List<File> filterList(final IOFileFilter filter, final Iterable<File> files) {
352         if (files == null) {
353             return Collections.emptyList();
354         }
355         return filterFiles(filter, StreamSupport.stream(files.spliterator(), false), Collectors.toList());
356     }
357 
358     /**
359      * <p>
360      * Applies an {@link IOFileFilter} to the provided {@link File}
361      * objects. The resulting set is a subset of the original file list that
362      * matches the provided filter.
363      * </p>
364      *
365      * <p>
366      * The {@link Set} returned by this method is not guaranteed to be thread safe.
367      * </p>
368      *
369      * <pre>
370      * Set&lt;File&gt; allFiles = ...
371      * Set&lt;File&gt; javaFiles = FileFilterUtils.filterSet(allFiles,
372      *     FileFilterUtils.suffixFileFilter(".java"));
373      * </pre>
374      *
375      * @param filter the filter to apply to the set of files.
376      * @param files the collection of files to apply the filter to.
377      * @return a subset of {@code files} that is accepted by the
378      *         file filter.
379      * @throws IllegalArgumentException if the filter is {@code null}
380      *         or {@code files} contains a {@code null} value.
381      *
382      * @since 2.0
383      */
384     public static Set<File> filterSet(final IOFileFilter filter, final File... files) {
385         return new HashSet<>(Arrays.asList(filter(filter, files)));
386     }
387 
388     /**
389      * <p>
390      * Applies an {@link IOFileFilter} to the provided {@link File}
391      * objects. The resulting set is a subset of the original file list that
392      * matches the provided filter.
393      * </p>
394      *
395      * <p>
396      * The {@link Set} returned by this method is not guaranteed to be thread safe.
397      * </p>
398      *
399      * <pre>
400      * Set&lt;File&gt; allFiles = ...
401      * Set&lt;File&gt; javaFiles = FileFilterUtils.filterSet(allFiles,
402      *     FileFilterUtils.suffixFileFilter(".java"));
403      * </pre>
404      *
405      * @param filter the filter to apply to the set of files.
406      * @param files the collection of files to apply the filter to.
407      * @return a subset of {@code files} that is accepted by the
408      *         file filter.
409      * @throws IllegalArgumentException if the filter is {@code null}
410      * @since 2.0
411      */
412     public static Set<File> filterSet(final IOFileFilter filter, final Iterable<File> files) {
413         if (files == null) {
414             return Collections.emptySet();
415         }
416         return filterFiles(filter, StreamSupport.stream(files.spliterator(), false), Collectors.toSet());
417     }
418 
419     /**
420      * Returns a filter that accepts files that begin with the provided magic
421      * number.
422      *
423      * @param magicNumber the magic number (byte sequence) to match at the
424      *        beginning of each file.
425      *
426      * @return an IOFileFilter that accepts files beginning with the provided
427      *         magic number.
428      *
429      * @throws IllegalArgumentException if {@code magicNumber} is
430      *         {@code null} or is of length zero.
431      * @see MagicNumberFileFilter
432      * @since 2.0
433      */
434     public static IOFileFilter magicNumberFileFilter(final byte[] magicNumber) {
435         return new MagicNumberFileFilter(magicNumber);
436     }
437 
438     /**
439      * Returns a filter that accepts files that contains the provided magic
440      * number at a specified offset within the file.
441      *
442      * @param magicNumber the magic number (byte sequence) to match at the
443      *        provided offset in each file.
444      * @param offset the offset within the files to look for the magic number.
445      * @return an IOFileFilter that accepts files containing the magic number
446      *         at the specified offset.
447      *
448      * @throws IllegalArgumentException if {@code magicNumber} is
449      *         {@code null}, or contains no bytes, or {@code offset}
450      *         is a negative number.
451      * @see MagicNumberFileFilter
452      * @since 2.0
453      */
454     public static IOFileFilter magicNumberFileFilter(final byte[] magicNumber, final long offset) {
455         return new MagicNumberFileFilter(magicNumber, offset);
456     }
457 
458     /**
459      * Returns a filter that accepts files that begin with the provided magic
460      * number.
461      *
462      * @param magicNumber the magic number (byte sequence) to match at the
463      *        beginning of each file.
464      *
465      * @return an IOFileFilter that accepts files beginning with the provided
466      *         magic number.
467      *
468      * @throws IllegalArgumentException if {@code magicNumber} is
469      *         {@code null} or the empty String.
470      * @see MagicNumberFileFilter
471      * @since 2.0
472      */
473     public static IOFileFilter magicNumberFileFilter(final String magicNumber) {
474         return new MagicNumberFileFilter(magicNumber);
475     }
476 
477     /**
478      * Returns a filter that accepts files that contains the provided magic
479      * number at a specified offset within the file.
480      *
481      * @param magicNumber the magic number (byte sequence) to match at the
482      *        provided offset in each file.
483      * @param offset the offset within the files to look for the magic number.
484      * @return an IOFileFilter that accepts files containing the magic number
485      *         at the specified offset.
486      *
487      * @throws IllegalArgumentException if {@code magicNumber} is
488      *         {@code null} or the empty String, or if offset is a
489      *         negative number.
490      * @see MagicNumberFileFilter
491      * @since 2.0
492      */
493     public static IOFileFilter magicNumberFileFilter(final String magicNumber, final long offset) {
494         return new MagicNumberFileFilter(magicNumber, offset);
495     }
496 
497     /**
498      * Decorates a filter to make it ignore CVS directories.
499      * Passing in {@code null} will return a filter that accepts everything
500      * except CVS directories.
501      *
502      * @param filter  the filter to decorate, null means an unrestricted filter.
503      * @return the decorated filter, never null.
504      * @since 1.1 (method existed but had a bug in 1.0)
505      */
506     public static IOFileFilter makeCVSAware(final IOFileFilter filter) {
507         return filter == null ? CVS_FILTER : and(filter, CVS_FILTER);
508     }
509 
510     /**
511      * Decorates a filter so that it only applies to directories and not to files.
512      *
513      * @param filter  the filter to decorate, null means an unrestricted filter.
514      * @return the decorated filter, never null.
515      * @see DirectoryFileFilter#DIRECTORY
516      * @since 1.3
517      */
518     public static IOFileFilter makeDirectoryOnly(final IOFileFilter filter) {
519         if (filter == null) {
520             return DirectoryFileFilter.DIRECTORY;
521         }
522         return DirectoryFileFilter.DIRECTORY.and(filter);
523     }
524 
525     /**
526      * Decorates a filter so that it only applies to files and not to directories.
527      *
528      * @param filter  the filter to decorate, null means an unrestricted filter.
529      * @return the decorated filter, never null.
530      * @see FileFileFilter#INSTANCE
531      * @since 1.3
532      */
533     public static IOFileFilter makeFileOnly(final IOFileFilter filter) {
534         if (filter == null) {
535             return FileFileFilter.INSTANCE;
536         }
537         return FileFileFilter.INSTANCE.and(filter);
538     }
539 
540     /**
541      * Decorates a filter to make it ignore SVN directories.
542      * Passing in {@code null} will return a filter that accepts everything
543      * except SVN directories.
544      *
545      * @param filter  the filter to decorate, null means an unrestricted filter.
546      * @return the decorated filter, never null.
547      * @since 1.1
548      */
549     public static IOFileFilter makeSVNAware(final IOFileFilter filter) {
550         return filter == null ? SVN_FILTER : and(filter, SVN_FILTER);
551     }
552 
553     /**
554      * Returns a filter that returns true if the file name matches the specified text.
555      *
556      * @param name  the file name.
557      * @return a name checking filter.
558      * @see NameFileFilter
559      */
560     public static IOFileFilter nameFileFilter(final String name) {
561         return new NameFileFilter(name);
562     }
563 
564     /**
565      * Returns a filter that returns true if the file name matches the specified text.
566      *
567      * @param name  the file name.
568      * @param ioCase  how to handle case sensitivity, null means case-sensitive.
569      * @return a name checking filter.
570      * @see NameFileFilter
571      * @since 2.0
572      */
573     public static IOFileFilter nameFileFilter(final String name, final IOCase ioCase) {
574         return new NameFileFilter(name, ioCase);
575     }
576 
577     /**
578      * Returns a filter that NOTs the specified filter.
579      *
580      * @param filter  the filter to invert.
581      * @return a filter that NOTs the specified filter.
582      * @see NotFileFilter
583      */
584     public static IOFileFilter notFileFilter(final IOFileFilter filter) {
585         return filter.negate();
586     }
587 
588     /**
589      * Returns a filter that ORs the specified filters.
590      *
591      * @param filters the IOFileFilters that will be ORed together.
592      * @return a filter that ORs the specified filters.
593      * @throws IllegalArgumentException if the filters are null or contain a
594      *         null value.
595      * @see OrFileFilter
596      * @since 2.0
597      */
598     public static IOFileFilter or(final IOFileFilter... filters) {
599         return new OrFileFilter(toList(filters));
600     }
601 
602     /**
603      * Returns a filter that ORs the two specified filters.
604      *
605      * @param filter1  the first filter.
606      * @param filter2  the second filter.
607      * @return a filter that ORs the two specified filters.
608      * @see #or(IOFileFilter...)
609      * @see OrFileFilter
610      * @deprecated Use {@link #or(IOFileFilter...)}
611      */
612     @Deprecated
613     public static IOFileFilter orFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) {
614         return new OrFileFilter(filter1, filter2);
615     }
616 
617     /**
618      * Returns a filter that returns true if the file name starts with the specified text.
619      *
620      * @param prefix  the file name prefix.
621      * @return a prefix checking filter.
622      * @see PrefixFileFilter
623      */
624     public static IOFileFilter prefixFileFilter(final String prefix) {
625         return new PrefixFileFilter(prefix);
626     }
627 
628     /**
629      * Returns a filter that returns true if the file name starts with the specified text.
630      *
631      * @param prefix  the file name prefix.
632      * @param ioCase  how to handle case sensitivity, null means case-sensitive.
633      * @return a prefix checking filter.
634      * @see PrefixFileFilter
635      * @since 2.0
636      */
637     public static IOFileFilter prefixFileFilter(final String prefix, final IOCase ioCase) {
638         return new PrefixFileFilter(prefix, ioCase);
639     }
640 
641     /**
642      * Returns a filter that returns true if the file is bigger than a certain size.
643      *
644      * @param threshold  the file size threshold.
645      * @return an appropriately configured SizeFileFilter.
646      * @see SizeFileFilter
647      * @since 1.2
648      */
649     public static IOFileFilter sizeFileFilter(final long threshold) {
650         return new SizeFileFilter(threshold);
651     }
652 
653     /**
654      * Returns a filter that filters based on file size.
655      *
656      * @param threshold  the file size threshold.
657      * @param acceptLarger  if true, larger files get accepted, if false, smaller.
658      * @return an appropriately configured SizeFileFilter.
659      * @see SizeFileFilter
660      * @since 1.2
661      */
662     public static IOFileFilter sizeFileFilter(final long threshold, final boolean acceptLarger) {
663         return new SizeFileFilter(threshold, acceptLarger);
664     }
665 
666     /**
667      * Returns a filter that accepts files whose size is &gt;= minimum size
668      * and &lt;= maximum size.
669      *
670      * @param minSizeInclusive the minimum file size (inclusive).
671      * @param maxSizeInclusive the maximum file size (inclusive).
672      * @return an appropriately configured IOFileFilter.
673      * @see SizeFileFilter
674      * @since 1.3
675      */
676     public static IOFileFilter sizeRangeFileFilter(final long minSizeInclusive, final long maxSizeInclusive) {
677         final IOFileFilter minimumFilter = new SizeFileFilter(minSizeInclusive, true);
678         final IOFileFilter maximumFilter = new SizeFileFilter(maxSizeInclusive + 1L, false);
679         return minimumFilter.and(maximumFilter);
680     }
681 
682     /**
683      * Returns a filter that returns true if the file name ends with the specified text.
684      *
685      * @param suffix  the file name suffix.
686      * @return a suffix checking filter.
687      * @see SuffixFileFilter
688      */
689     public static IOFileFilter suffixFileFilter(final String suffix) {
690         return new SuffixFileFilter(suffix);
691     }
692 
693     /**
694      * Returns a filter that returns true if the file name ends with the specified text.
695      *
696      * @param suffix  the file name suffix.
697      * @param ioCase  how to handle case sensitivity, null means case-sensitive.
698      * @return a suffix checking filter.
699      * @see SuffixFileFilter
700      * @since 2.0
701      */
702     public static IOFileFilter suffixFileFilter(final String suffix, final IOCase ioCase) {
703         return new SuffixFileFilter(suffix, ioCase);
704     }
705 
706     /**
707      * Create a List of file filters.
708      *
709      * @param filters The file filters.
710      * @return The list of file filters.
711      * @throws NullPointerException if the filters are null or contain a
712      *         null value.
713      * @since 2.0
714      */
715     public static List<IOFileFilter> toList(final IOFileFilter... filters) {
716         return Stream.of(Objects.requireNonNull(filters, "filters")).map(Objects::requireNonNull).collect(Collectors.toList());
717     }
718 
719     /**
720      * Returns a filter that always returns true.
721      *
722      * @return a true filter.
723      * @see TrueFileFilter#TRUE
724      */
725     public static IOFileFilter trueFileFilter() {
726         return TrueFileFilter.TRUE;
727     }
728 
729     /**
730      * FileFilterUtils is not normally instantiated.
731      */
732     public FileFilterUtils() {
733     }
734 
735 }