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.IOException;
21  import java.io.Serializable;
22  import java.nio.file.FileVisitResult;
23  import java.nio.file.Files;
24  import java.nio.file.Path;
25  import java.nio.file.attribute.BasicFileAttributes;
26  
27  /**
28   * Filters files based on size, can filter either smaller files or
29   * files equal to or larger than a given threshold.
30   * <p>
31   * For example, to print all files and directories in the
32   * current directory whose size is greater than 1 MB:
33   * </p>
34   * <h2>Using Classic IO</h2>
35   * <pre>
36   * File dir = FileUtils.current();
37   * String[] files = dir.list(new SizeFileFilter(1024 * 1024));
38   * for (String file : files) {
39   *     System.out.println(file);
40   * }
41   * </pre>
42   *
43   * <h2>Using NIO</h2>
44   * <pre>
45   * final Path dir = PathUtils.current();
46   * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new SizeFileFilter(1024 * 1024));
47   * //
48   * // Walk one dir
49   * Files.<b>walkFileTree</b>(dir, Collections.emptySet(), 1, visitor);
50   * System.out.println(visitor.getPathCounters());
51   * System.out.println(visitor.getFileList());
52   * //
53   * visitor.getPathCounters().reset();
54   * //
55   * // Walk dir tree
56   * Files.<b>walkFileTree</b>(dir, visitor);
57   * System.out.println(visitor.getPathCounters());
58   * System.out.println(visitor.getDirList());
59   * System.out.println(visitor.getFileList());
60   * </pre>
61   * <h2>Deprecating Serialization</h2>
62   * <p>
63   * <em>Serialization is deprecated and will be removed in 3.0.</em>
64   * </p>
65   *
66   * @since 1.2
67   * @see FileFilterUtils#sizeFileFilter(long)
68   * @see FileFilterUtils#sizeFileFilter(long, boolean)
69   * @see FileFilterUtils#sizeRangeFileFilter(long, long)
70   */
71  public class SizeFileFilter extends AbstractFileFilter implements Serializable {
72  
73      private static final long serialVersionUID = 7388077430788600069L;
74  
75      /** Whether the files accepted will be larger or smaller. */
76      private final boolean acceptLarger;
77  
78      /** The size threshold. */
79      private final long size;
80  
81      /**
82       * Constructs a new size file filter for files equal to or
83       * larger than a certain size.
84       *
85       * @param size  the threshold size of the files
86       * @throws IllegalArgumentException if the size is negative
87       */
88      public SizeFileFilter(final long size) {
89          this(size, true);
90      }
91  
92      /**
93       * Constructs a new size file filter for files based on a certain size
94       * threshold.
95       *
96       * @param size  the threshold size of the files
97       * @param acceptLarger  if true, files equal to or larger are accepted,
98       * otherwise smaller ones (but not equal to)
99       * @throws IllegalArgumentException if the size is negative
100      */
101     public SizeFileFilter(final long size, final boolean acceptLarger) {
102         if (size < 0) {
103             throw new IllegalArgumentException("The size must be non-negative");
104         }
105         this.size = size;
106         this.acceptLarger = acceptLarger;
107     }
108 
109     /**
110      * Checks to see if the size of the file is favorable.
111      * <p>
112      * If size equals threshold and smaller files are required,
113      * file <b>IS NOT</b> selected.
114      * If size equals threshold and larger files are required,
115      * file <b>IS</b> selected.
116      * </p>
117      *
118      * @param file  the File to check
119      * @return true if the file name matches
120      */
121     @Override
122     public boolean accept(final File file) {
123         return accept(file != null ? file.length() : 0);
124     }
125 
126     private boolean accept(final long length) {
127         return acceptLarger != length < size;
128     }
129 
130     /**
131      * Checks to see if the size of the file is favorable.
132      * <p>
133      * If size equals threshold and smaller files are required,
134      * file <b>IS NOT</b> selected.
135      * If size equals threshold and larger files are required,
136      * file <b>IS</b> selected.
137      * </p>
138      * @param file  the File to check
139      *
140      * @return true if the file name matches
141      */
142     @Override
143     public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
144         return get(() -> toFileVisitResult(accept(Files.size(file))));
145     }
146 
147     /**
148      * Provide a String representation of this file filter.
149      *
150      * @return a String representation
151      */
152     @Override
153     public String toString() {
154         final String condition = acceptLarger ? ">=" : "<";
155         return super.toString() + "(" + condition + size + ")";
156     }
157 
158     @Override
159     public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
160         return toFileVisitResult(accept(Files.size(file)));
161     }
162 
163 }