1

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

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

上面的代码只是列出了文件。我可以做的另一件事是我必须将文件和目录列表存储在一个列表中,然后在另一个循环中处理。但我无法想出我想要的伪代码。我是文件目录的新手,请帮忙。提前致谢。

4

6 回答 6

3

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

这里有一个关于它的用法的简短教程。

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

于 2013-08-13T13:22:46.310 回答
1

在 Java 7 中遍历目录树时,请使用PathsandFiles功能。它们不仅简化了目录和文件的读取,而且比“旧”File方式更快。

假设您有两个目录:mainDir并且otherDir您想遍历所有目录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
  • Path并且BasicFileAttributes不是Serializable,所以没有简单的方法可以在两台不同的机器上进行此步行。
于 2013-08-13T14:16:49.387 回答
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
        }
    }
}
于 2013-08-13T12:33:40.163 回答
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;
}
于 2013-08-13T12:33:53.227 回答
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());
        }
    }
}
于 2013-08-13T12:36:33.457 回答
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());
    }
}
于 2013-08-13T12:40:06.693 回答