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.Serializable;
21  import java.nio.file.FileVisitResult;
22  import java.nio.file.Files;
23  import java.nio.file.Path;
24  import java.nio.file.attribute.BasicFileAttributes;
25  import java.util.stream.Stream;
26  
27  import org.apache.commons.io.IOUtils;
28  
29  /**
30   * This filter accepts files or directories that are empty.
31   * <p>
32   * If the {@link File} is a directory it checks that it contains no files.
33   * </p>
34   * <p>
35   * Example, showing how to print out a list of the current directory's empty files/directories:
36   * </p>
37   * <h2>Using Classic IO</h2>
38   * <pre>
39   * File dir = FileUtils.current();
40   * String[] files = dir.list(EmptyFileFilter.EMPTY);
41   * for (String file : files) {
42   *     System.out.println(file);
43   * }
44   * </pre>
45   *
46   * <p>
47   * Example, showing how to print out a list of the current directory's non-empty files/directories:
48   * </p>
49   *
50   * <pre>
51   * File dir = FileUtils.current();
52   * String[] files = dir.list(EmptyFileFilter.NOT_EMPTY);
53   * for (String file : files) {
54   *     System.out.println(file);
55   * }
56   * </pre>
57   *
58   * <h2>Using NIO</h2>
59   * <pre>
60   * final Path dir = PathUtils.current();
61   * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(EmptyFileFilter.EMPTY);
62   * //
63   * // Walk one directory
64   * Files.<strong>walkFileTree</strong>(dir, Collections.emptySet(), 1, visitor);
65   * System.out.println(visitor.getPathCounters());
66   * System.out.println(visitor.getFileList());
67   * //
68   * visitor.getPathCounters().reset();
69   * //
70   * // Walk directory tree
71   * Files.<strong>walkFileTree</strong>(dir, visitor);
72   * System.out.println(visitor.getPathCounters());
73   * System.out.println(visitor.getDirList());
74   * System.out.println(visitor.getFileList());
75   * </pre>
76   * <h2>Deprecating Serialization</h2>
77   * <p>
78   * <em>Serialization is deprecated and will be removed in 3.0.</em>
79   * </p>
80   *
81   * @since 1.3
82   */
83  public class EmptyFileFilter extends AbstractFileFilter implements Serializable {
84  
85      /** Singleton instance of <em>empty</em> filter */
86      public static final IOFileFilter EMPTY = new EmptyFileFilter();
87  
88      /** Singleton instance of <em>not-empty</em> filter */
89      public static final IOFileFilter NOT_EMPTY = EMPTY.negate();
90  
91      private static final long serialVersionUID = 3631422087512832211L;
92  
93      /**
94       * Restrictive constructor.
95       */
96      protected EmptyFileFilter() {
97      }
98  
99      /**
100      * Tests to see if the file is empty.
101      *
102      * @param file the file or directory to check
103      * @return {@code true} if the file or directory is <em>empty</em>, otherwise {@code false}.
104      */
105     @Override
106     public boolean accept(final File file) {
107         if (file == null) {
108             return true;
109         }
110         if (file.isDirectory()) {
111             final File[] files = file.listFiles();
112             return IOUtils.length(files) == 0;
113         }
114         return file.length() == 0;
115     }
116 
117     /**
118      * Tests to see if the file is empty.
119      *
120      * @param file the file or directory to check
121      * @param attributes the path's basic attributes (may be null).
122      * @return {@code true} if the file or directory is <em>empty</em>, otherwise {@code false}.
123      * @since 2.9.0
124      */
125     @Override
126     public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
127         if (file == null) {
128             return toFileVisitResult(true);
129         }
130         return get(() -> {
131             if (Files.isDirectory(file)) {
132                 try (Stream<Path> stream = Files.list(file)) {
133                     return toFileVisitResult(!stream.findFirst().isPresent());
134                 }
135             }
136             return toFileVisitResult(Files.size(file) == 0);
137         });
138     }
139 
140 }