[英]Recursively process same files inside many sub directories in Java
Hi I would like to process files inside many sub directories using Java. 嗨,我想使用Java处理许多子目录中的文件。 Psuedo code would be
Psuedo代码将是
while(mainDir.hasMoreDirectory())
{
getFilesFromCurrentDirectory()
passThoseFilesAsArgumentToProcess()
}
I am currently using the following code 我目前正在使用以下代码
public void list(File file) {
System.out.println(file.getName());
File[] children = file.listFiles();
for (File child : children) {
list(child);
}
}
Above code just lists files. 上面的代码只列出文件。 Other thing I can do is I have to store list of files and directories in a list and then process in another loop.
我能做的其他事情是我必须在列表中存储文件和目录列表,然后在另一个循环中处理。 But I am not able to come up with what I want as show in pseudo code.
但我无法想出伪代码中显示的内容。 I am new to Files Directories please help.
我是文件目录的新手,请帮忙。 Thanks in advance.
提前致谢。
If you are using Java 7, you can harness the enhanced functionality of NIO in the form of the Files.walkFileTree method. 如果您使用的是Java 7,则可以使用Files.walkFileTree方法的形式利用NIO的增强功能。 Traversing the file system has never been easier in Java.
在Java中遍历文件系统从未如此简单。
There is a short tutorial on it's usage here . 有它的使用一个简短的教程这里 。
It implements the visitor pattern so you don't need to worry about the traversal algorithm itself, only specify what you want to do with each entry. 它实现了访问者模式,因此您无需担心遍历算法本身,只需指定您要对每个条目执行的操作。
When traveling a directory tree in Java 7 use the Paths
and Files
functionality. 在Java 7中运行目录树时,请使用“
Paths
和Files
功能。 They not only ease reading of directories and files, they're way faster then the "old" File
way. 它们不仅简化了目录和文件的读取,而且比“旧”
File
方式更快。
Assume you have two directories: mainDir
and otherDir
and you want to walk thru all directories of mainDir
down to its leaves. 假设你有两个目录:
mainDir
和otherDir
,你想要通过mainDir
所有目录到它的叶子。 With each entry in maiondir
(file, sub-directory, symbolic link, ...) you want to compare this entry and its attributes (size, modification time, ...) against the entry at the same position in the otherDir
. 对于
maiondir
每个条目(文件,子目录,符号链接,...),您希望将此条目及其属性(大小,修改时间......)与otherDir
相同位置的条目进行otherDir
。 Then this would be your code: 那么这将是你的代码:
public final void test() throws IOException, InterruptedException {
final Path mainDir = Paths.get("absolute path to your main directory to read from");
final Path otherDir = Paths.get("absolute path to your other directory to compare");
// Walk thru mainDir directory
Files.walkFileTree(mainDir, new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path path,
BasicFileAttributes atts) throws IOException {
return visitFile(path, atts);
}
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes mainAtts)
throws IOException {
// I've seen two implementations on windows and MacOSX. One has passed the relative path, one the absolute path.
// This works in both cases
Path relativePath = mainDir.relativize(mainDir.resolve(path));
BasicFileAttributes otherAtts = Files.readAttributes(otherDir.resolve(relativePath), BasicFileAttributes.class);
// Do your comparison logic here:
compareEntries(mainDir, otherDir, relativePath, mainAtts, otherAtts);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path path,
IOException exc) throws IOException {
// TODO Auto-generated method stub
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path path, IOException exc)
throws IOException {
exc.printStackTrace();
// If the root directory has failed it makes no sense to continue
return (path.equals(mainDir))? FileVisitResult.TERMINATE:FileVisitResult.CONTINUE;
}
});
}
What it not does: 它没有做什么:
otherDir
but not in maindir
otherDir
存在但在maindir
中不存在的条目 Path
and BasicFileAttributes
are not Serializable
, so there's no easy way to do this walk on two different machines. Path
和BasicFileAttributes
不是Serializable
,因此没有简单的方法可以在两台不同的机器上执行此操作。 Will following do? 会跟着吗?
public void list(File file) {
File[] children = file.listFiles();
if (children != null) {
process(children);
for (File child : children) {
if (child.isDirectory()) {
list(child);
}
}
} else {
process(new File[]{file});
}
}
private void process(File[] children) {
for (File child : children) {
if (child.isFile()) {
// process normal file
}
}
}
A method like this would return you a List
of all the files recursively within a directory. 像这样的方法会在目录中递归返回所有文件的
List
。 You can either operate on the returned List
or replace the rtn.add
calls with your processing. 您可以对返回的
List
进行操作,也可以使用您的处理替换rtn.add
调用。
Beware that this method doesn't have anything to stop it getting stuck in circular symlinks. 请注意,此方法没有任何东西可以阻止它卡在循环符号链接中。
public static List<File> getFilesRecursive(File s)
{
ArrayList<File> rtn = new ArrayList<File>();
File[] contents = s.listFiles();
for(int i = 0; i<contents.length; i++)
{
if(contents[i].isDirectory()){
rtn.addAll(getFilesRecursive(contents[i]));
}else{
rtn.add(contents[i]);
}
}
return rtn;
}
Maybe this piece of code helps you: 也许这段代码可以帮助你:
public void traverse(String path) {
File root = new File(path);
File[] list = root.listFiles();
if (list == null) return;
for (File file : list) {
if (file.isDirectory()) {
traverse(file.getAbsolutePath());
System.out.println("Directory: " + file.getAbsoluteFile());
} else {
System.out.println("File: " + file.getAbsoluteFile());
}
}
}
private static List<File> allFiles = new ArrayList<File>();
private static void processFiles(String rootDirectory) {
File rootDir = new File(rootDirectory);
if (rootDir.exists()) {
traverseDirectories(rootDir);
}
}
private static void traverseDirectories(File file) {
// add all files and directories to list.
allFiles.add(file);
if (file.isDirectory()) {
File[] fileList = file.listFiles();
for (File fileHandle : fileList) {
traverseDirectories(fileHandle);
}
} else {
// call to process file
System.out.println("Call to process file " + file.getAbsolutePath());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.