我需要在文件列表中应用更复杂的逻辑。具体来说,在应用软件更新时,我想对从更新zip存档获取的文件执行此操作:
updateFile
成为更新存档中的文件,originalFile
是当前版本文件,backupFile
是原始文件的备份originalFile
与当前正在运行的jar
文件相同,请跳过updateFile
的父目录是特定名称,请跳过它(例如,带有用户数据的目录)我希望有一些选项,例如为每个文件运行回调:
GreatFileLibrary.forEveryChildOf(new File("my path"),
(File child)->{ ... logic here ... });
如果不是这样,那么至少只需获取某些Collection
中的所有文件并循环播放它:
Iterable<File> files = GreatFileLibrary.listChildren(new File("my path"));
for(File child:files) {
... logic ...
}
前者允许我显示进度(感谢知道列表长度)但我坦率地假设更新几乎是即时的。
文件当然可以返回一些孩子的列表,所以超级天真的方法是:
/** Returns list of all child files, recursively. **/
public static Iterable<File> listFileChildren(File parent, ArrayList<File> list) {
File[] files = parent.listFiles();
for(File file:files) {
list.add(file);
if(file.isDirectory())
listFileChildren(file, list);
}
return list;
}
public static Iterable<File> listFileChildren(File parent) {
return listFileChildren(parent, new ArrayList());
}
内置Java 8库能做得更好吗?我的快速代码有缺陷吗?我会真的感谢您删除File[]
转换为Iterable<File>
,就像我的代码一样,这很脏。
答案 0 :(得分:2)
代码中的列表创建将耗费大量时间,因此请尽量避免使用它。 一个简单的方法是:
public void forEveryChildOf(File file) {
for(File child:file.listFiles())
doForEach(file,child);
}
private void doForEach(File topParent,File child){
if(child.isFile())
System.out.println("Do logic");
if(child.isDirectory())
for(File subchild:child.listFiles())
doForEach(topParent,subchild);
}
答案 1 :(得分:1)
如果您不介意创建多个流的性能影响,此函数将返回目标文件夹中每个子项的流。
以下版本使用了Java 7
的{{1}}和Files
类,因此您可能需要重写某些内容(或调用Path
)
Path#toFile
此版本使用普通的public static Stream<Path> stream(Path path) {
try {
return Files.isDirectory(path) ? Files.list(path).map(innerpath -> stream(innerpath)).flatMap(s -> s) : Stream.of(path);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
s
File
您可以在最终public static Stream<File> stream(File file) {
return file.isDirectory() ? Arrays.stream(file.listFiles()).map(innerfile -> stream(innerfile)).flatMap(s -> s) : Stream.of(file);
}
收集List
或致电forEach
。
答案 2 :(得分:0)
public void allFiles(File raiz) {
for (File arquivo : raiz.listFiles(filtro)) {
if (arquivo.isFile()) {
try {
System.out.println(arquivo);
} catch (Exception e) {
System.out.println("erro" +arquivo);
}
} else {
allFiles(arquivo);
}
}
}
答案 3 :(得分:0)
FileVisitor
:
Path startPath = new File("...").toPath();
Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
//your logic
return FileVisitResult.CONTINUE;
}
});