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.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 dir 64 * Files.<b>walkFileTree</b>(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 dir tree 71 * Files.<b>walkFileTree</b>(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 <i>empty</i> filter */ 86 public static final IOFileFilter EMPTY = new EmptyFileFilter(); 87 88 /** Singleton instance of <i>not-empty</i> 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 * Checks 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 <i>empty</i>, 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 * Checks to see if the file is empty. 119 * @param file the file or directory to check 120 * 121 * @return {@code true} if the file or directory is <i>empty</i>, otherwise {@code false}. 122 * @since 2.9.0 123 */ 124 @Override 125 public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { 126 if (file == null) { 127 return toFileVisitResult(true); 128 } 129 return get(() -> { 130 if (Files.isDirectory(file)) { 131 try (Stream<Path> stream = Files.list(file)) { 132 return toFileVisitResult(!stream.findFirst().isPresent()); 133 } 134 } 135 return toFileVisitResult(Files.size(file) == 0); 136 }); 137 } 138 139 }