簡體   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