繁体   English   中英

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

[英]Recursively process same files inside many sub directories in 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);
    }
}

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

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

有它的使用一个简短的教程这里

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

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

假设你有两个目录: mainDirotherDir ,你想要通过mainDir所有目录到它的叶子。 对于maiondir每个条目(文件,子目录,符号链接,...),您希望将此条目及其属性(大小,修改时间......)与otherDir相同位置的条目进行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 ,因此没有简单的方法可以在两台不同的机器上执行此操作。

会跟着吗?

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

像这样的方法会在目录中递归返回所有文件的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;
}

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

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM