• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Serializable;
21 import java.nio.file.FileVisitResult;
22 import java.nio.file.Path;
23 import java.nio.file.attribute.BasicFileAttributes;
24 import java.time.Instant;
25 import java.util.Date;
26 
27 import org.apache.commons.io.FileUtils;
28 import org.apache.commons.io.file.PathUtils;
29 
30 /**
31  * Filters files based on a cutoff time, can filter either newer files or files equal to or older.
32  * <p>
33  * For example, to print all files and directories in the current directory older than one day:
34  * </p>
35  * <h2>Using Classic IO</h2>
36  * <pre>
37  * Path dir = PathUtils.current();
38  * // We are interested in files older than one day
39  * Instant cutoff = Instant.now().minus(Duration.ofDays(1));
40  * String[] files = dir.list(new AgeFileFilter(cutoff));
41  * for (String file : files) {
42  *     System.out.println(file);
43  * }
44  * </pre>
45  *
46  * <h2>Using NIO</h2>
47  * <pre>
48  * Path dir = PathUtils.current();
49  * // We are interested in files older than one day
50  * Instant cutoff = Instant.now().minus(Duration.ofDays(1));
51  * AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new AgeFileFilter(cutoff));
52  * //
53  * // Walk one dir
54  * Files.<b>walkFileTree</b>(dir, Collections.emptySet(), 1, visitor);
55  * System.out.println(visitor.getPathCounters());
56  * System.out.println(visitor.getFileList());
57  * //
58  * visitor.getPathCounters().reset();
59  * //
60  * // Walk dir tree
61  * Files.<b>walkFileTree</b>(dir, visitor);
62  * System.out.println(visitor.getPathCounters());
63  * System.out.println(visitor.getDirList());
64  * System.out.println(visitor.getFileList());
65  * </pre>
66  *
67  * @see FileFilterUtils#ageFileFilter(Date)
68  * @see FileFilterUtils#ageFileFilter(File)
69  * @see FileFilterUtils#ageFileFilter(long)
70  * @see FileFilterUtils#ageFileFilter(Date, boolean)
71  * @see FileFilterUtils#ageFileFilter(File, boolean)
72  * @see FileFilterUtils#ageFileFilter(long, boolean)
73  * @since 1.2
74  */
75 public class AgeFileFilter extends AbstractFileFilter implements Serializable {
76 
77     private static final long serialVersionUID = -2132740084016138541L;
78 
79     /** Whether the files accepted will be older or newer. */
80     private final boolean acceptOlder;
81 
82     /** The cutoff time threshold measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970). */
83     private final Instant cutoffInstant;
84 
85     /**
86      * Constructs a new age file filter for files older than (at or before) a certain cutoff date.
87      *
88      * @param cutoffDate the threshold age of the files
89      */
AgeFileFilter(final Date cutoffDate)90     public AgeFileFilter(final Date cutoffDate) {
91         this(cutoffDate, true);
92     }
93 
94     /**
95      * Constructs a new age file filter for files on any one side of a certain cutoff date.
96      *
97      * @param cutoffDate the threshold age of the files
98      * @param acceptOlder if true, older files (at or before the cutoff) are accepted, else newer ones (after the
99      *        cutoff).
100      */
AgeFileFilter(final Date cutoffDate, final boolean acceptOlder)101     public AgeFileFilter(final Date cutoffDate, final boolean acceptOlder) {
102         this(cutoffDate.toInstant(), acceptOlder);
103     }
104 
105     /**
106      * Constructs a new age file filter for files older than (at or before) a certain File (whose last modification time
107      * will be used as reference).
108      *
109      * @param cutoffReference the file whose last modification time is used as the threshold age of the files
110      */
AgeFileFilter(final File cutoffReference)111     public AgeFileFilter(final File cutoffReference) {
112         this(cutoffReference, true);
113     }
114 
115     /**
116      * Constructs a new age file filter for files on any one side of a certain File (whose last modification time will
117      * be used as reference).
118      *
119      * @param cutoffReference the file whose last modification time is used as the threshold age of the files
120      * @param acceptOlder if true, older files (at or before the cutoff) are accepted, else newer ones (after the
121      *        cutoff).
122      */
AgeFileFilter(final File cutoffReference, final boolean acceptOlder)123     public AgeFileFilter(final File cutoffReference, final boolean acceptOlder) {
124         this(FileUtils.lastModifiedUnchecked(cutoffReference), acceptOlder);
125     }
126 
127     /**
128      * Constructs a new age file filter for files equal to or older than a certain cutoff.
129      *
130      * @param cutoffInstant The cutoff time threshold since the epoch (00:00:00 GMT, January 1, 1970).
131      * @since 2.12.0
132      */
AgeFileFilter(final Instant cutoffInstant)133     public AgeFileFilter(final Instant cutoffInstant) {
134         this(cutoffInstant, true);
135     }
136 
137     /**
138      * Constructs a new age file filter for files on any one side of a certain cutoff.
139      *
140      * @param cutoffInstant The cutoff time threshold since the epoch (00:00:00 GMT, January 1, 1970).
141      * @param acceptOlder if true, older files (at or before the cutoff) are accepted, else newer ones (after the cutoff).
142      * @since 2.12.0
143      */
AgeFileFilter(final Instant cutoffInstant, final boolean acceptOlder)144     public AgeFileFilter(final Instant cutoffInstant, final boolean acceptOlder) {
145         this.acceptOlder = acceptOlder;
146         this.cutoffInstant = cutoffInstant;
147     }
148 
149     /**
150      * Constructs a new age file filter for files equal to or older than a certain cutoff
151      *
152      * @param cutoffMillis The cutoff time threshold measured in milliseconds since the epoch (00:00:00 GMT, January 1,
153      *        1970).
154      */
AgeFileFilter(final long cutoffMillis)155     public AgeFileFilter(final long cutoffMillis) {
156         this(Instant.ofEpochMilli(cutoffMillis), true);
157     }
158 
159     /**
160      * Constructs a new age file filter for files on any one side of a certain cutoff.
161      *
162      * @param cutoffMillis The cutoff time threshold measured in milliseconds since the epoch (00:00:00 GMT, January 1,
163      *        1970).
164      * @param acceptOlder if true, older files (at or before the cutoff) are accepted, else newer ones (after the
165      *        cutoff).
166      */
AgeFileFilter(final long cutoffMillis, final boolean acceptOlder)167     public AgeFileFilter(final long cutoffMillis, final boolean acceptOlder) {
168         this(Instant.ofEpochMilli(cutoffMillis), acceptOlder);
169     }
170 
171     /**
172      * Checks to see if the last modification of the file matches cutoff favorably.
173      * <p>
174      * If last modification time equals cutoff and newer files are required, file <b>IS NOT</b> selected. If last
175      * modification time equals cutoff and older files are required, file <b>IS</b> selected.
176      * </p>
177      *
178      * @param file the File to check
179      * @return true if the file name matches
180      */
181     @Override
accept(final File file)182     public boolean accept(final File file) {
183         return acceptOlder != FileUtils.isFileNewer(file, cutoffInstant);
184     }
185 
186     /**
187      * Checks to see if the last modification of the file matches cutoff favorably.
188      * <p>
189      * If last modification time equals cutoff and newer files are required, file <b>IS NOT</b> selected. If last
190      * modification time equals cutoff and older files are required, file <b>IS</b> selected.
191      * </p>
192      * @param file the File to check
193      *
194      * @return true if the file name matches
195      * @since 2.9.0
196      */
197     @Override
accept(final Path file, final BasicFileAttributes attributes)198     public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
199         return get(() -> toFileVisitResult(acceptOlder != PathUtils.isNewer(file, cutoffInstant)));
200     }
201 
202     /**
203      * Provide a String representation of this file filter.
204      *
205      * @return a String representation
206      */
207     @Override
toString()208     public String toString() {
209         final String condition = acceptOlder ? "<=" : ">";
210         return super.toString() + "(" + condition + cutoffInstant + ")";
211     }
212 }
213