在Java中以递归方式处理许多子目录中的相同文件

时间:2013-08-13 12:23:56

标签: java

您好我想使用Java处理许多子目录中的文件。 Psuedo代码将是

while(mainDir.hasMoreDirectory())
{
   getFilesFromCurrentDirectory()
   passThoseFilesAsArgumentToProcess()
}

我目前正在使用以下代码

public void list(File file) {
    System.out.println(file.getName());
    File[] children = file.listFiles();
    for (File child : children) {
        list(child);
    }
}

以上代码只列出文件。我能做的其他事情是我必须在列表中存储文件和目录列表,然后在另一个循环中处理。但我无法想出伪代码中显示的内容。我是文件目录的新手,请帮忙。提前谢谢。

6 个答案:

答案 0 :(得分:3)

如果您使用的是Java 7,则可以使用Files.walkFileTree方法的形式利用NIO的增强功能。在Java中遍历文件系统从未如此简单。

有一个关于它的使用here的简短教程。

它实现了访问者模式,因此您无需担心遍历算法本身,只需指定您要对每个条目执行的操作。

答案 1 :(得分:1)

在Java 7中旅行目录树时,请使用PathsFiles功能。它们不仅可以轻松读取目录和文件,而且比“旧”File方式更快。<​​/ p>

假设您有两个目录:mainDirotherDir,并且您想要通过mainDir的所有目录直到它的叶子。对于maiondir中的每个条目(文件,子目录,符号链接,...),您希望将此条目及其属性(大小,修改时间......)与相同位置的条目进行比较。 otherDir。 那么这就是你的代码:

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;
        }
    });
}

的含义:

  • 查找otherDir但不存在于maindir
  • 中的条目
  • PathBasicFileAttributes不是Serializable,因此在两台不同的机器上进行此操作并不容易。

答案 2 :(得分:0)

以下会这样做吗?

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
        }
    }
}

答案 3 :(得分:0)

这样的方法会在目录中递归返回所有文件的List。您可以对返回的List进行操作,也可以使用您的处理替换rtn.add来电。

请注意,此方法无法阻止它陷入循环符号链接。

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;
}

答案 4 :(得分:0)

也许这段代码可以帮助你:

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());
        }
    }
}

答案 5 :(得分:0)

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());
    }
}