我能够找到所有我想要的结尾为.zip的扩展名的文件。
但是我很想根据修改日期在两个日期之间进一步过滤。
我到处搜索,找到了仅用于.zip或仅用于日期的方法。我已经可以做到,但不能递归地查找目录和子目录
如下所示,我创建了一个FileFilterDateIntervalUtils
(稍后添加),我希望对.zip(或其他要配置的)进行过滤,并将时间范围过滤为{{ 1}}。我想以某种方式将其添加到步行中,但是我对此并不陌生。
accept
答案 0 :(得分:3)
您可以使用Java中的内置机制来“遍历”文件树,称为FileVisitor。它可以进行所有遍历和递归遍历-您只需要提供访问每个文件时该怎么做的逻辑即可。
作为一个额外的好处,它在某种意义上具有隐式的性能优化,即它不会将所有路径都加载到内存中,而是一个一个地“遍历”文件/目录,这对于其中包含许多文件/目录的目录很有用。
这是一个可行的示例:
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
public class Example {
public static void main(String[] args) throws IOException {
// walks the file tree starting from current directory '.', using an
// instance of anonymous class that implements FileVisitor interface
Files.walkFileTree(Paths.get("."), new FileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path,
BasicFileAttributes attrs) {
// some starting date
Date start = new Date();
// some ending date
Date end = new Date();
if (path.endsWith(".zip") &&
(attrs.creationTime().toMillis() >= start.getTime() &&
attrs.creationTime().toMillis() <= end.getTime())) {
// if you use Java 8 or later, you can work with Instant, like this
// attrs.creationTime().toInstant().isAfter(start.toInstant())
System.out.println(path);
// or optionally convert to File and do something with it
File file = path.toFile();
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file,
IOException exc) {
// unused
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir,
IOException exc) {
// unused
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) {
// unused
return FileVisitResult.CONTINUE;
}
});
}
答案 1 :(得分:1)
这就是Apache的IOUtils
类的用途。重做您的代码,使其调用IOUtils.listFiles()
。此方法列出目录中的文件。利用Apache的IOFileFilter
,以便根据您需要的lastModified()
日期标准过滤掉文件。这样可以满足您的需求。
答案 2 :(得分:0)
我能够执行我在上述问题中想要做的事情。我仍然想测试Danilo Radenovic提供的答案。我确实需要为日期添加参数。...并不困难。我还需要清理:FileFilterDateIntervalUtils.java
public class App {
public static void main(String[] args) {
String dirName = "";
String extension = "";
Finder find = new Finder();
System.out.println("Args Length: " + args.length);
if (args.length != 2) {
System.out.println("You need to include two arguments, the root directory and the extension to search");
} else {
dirName = args[0];
extension = args[1];
}
System.out.println("Using starting directory " + dirName);
System.out.println("Using extension " + extension);
find.finder_walkFileTree(dirName, extension);
}
}
public class Finder {
public void finder_walkFileTree(String dirName, String extension) {
try {
Path p1 = Paths.get(dirName);
System.out.println("Path: " + p1.toString());
FileFilterDateIntervalUtils filter_date = new FileFilterDateIntervalUtils("2019-08-17 00:00:00 AM",
"2019-08-22 12:00:00 PM");
Files.walkFileTree(p1, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String fileString = file.toAbsolutePath().toString();
if (filter_date.accept(dirName, fileString, extension)) {
System.out.println("file found at path: " + file.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class FileFilterDateIntervalUtils implements FilenameFilter {
String dateStart;
String dateEnd;
SimpleDateFormat sdf;
public FileFilterDateIntervalUtils(String dateStart, String dateEnd) {
this.dateStart = dateStart;
this.dateEnd = dateEnd;
sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a");
}
public boolean accept(String dir, String name, String extension) {
Date d = new Date(new File(name).lastModified());
String current = sdf.format(d);
if (!name.endsWith(extension)) {
return false;
} else {
System.out.println("found zip " + name);
System.out.println("Current date: " + current);
System.out.println("Start date: " + dateStart);
System.out.println("End date: " + dateEnd);
if((dateStart.compareTo(current) < 0 && (dateEnd.compareTo(current) >= 0))) {
System.out.println("We are within the date range!");
return true;
}
return false;
}
}
public Predicate<? super Path> accept(Stream<Path> paths) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
return false;
}
}