Java 文件樹

2018-02-05 14:12 更新

Java IO教程 - Java文件樹


FileVisitor API可以遞歸地處理文件樹中的所有文件和目錄。

當我們要對文件樹中的所有或某些文件或目錄執(zhí)行某些操作時,F(xiàn)ileVisitor API非常有用。

SimpleFileVisitor類是FileVisitor接口的基本實現(xiàn)。

當訪問文件/目錄時,SimpleFileVisitor類不執(zhí)行任何操作。我們可以從SimpleFileVisitor類繼承我們的文件訪問類,并且只覆蓋適合我們需要的方法。

FileVisitor接口的方法:

ID含義
1FileVisitResult preVisitDirectory(T dir,BasicFileAttributes attrs) 在訪問目錄中的條目之前調(diào)用一次。
2FileVisitResult postVisitDirectory(T dir,IOException exc) 已訪問目錄中的后調(diào)用項。如果在目錄的迭代期間拋出了任何異常,則將異常對象作為第二個參數(shù)傳遞給此方法。如果此方法的第二個參數(shù)為null,則在目錄迭代期間沒有異常。
3FileVisitResult visitFile(T文件,BasicFileAttributes attrs) 當訪問目錄中的文件時調(diào)用。
4FileVisitResult visitFileFailed(T文件,IOException exc) 當由于任何原因而無法訪問文件或目錄時調(diào)用。

下表列出了FileVisitResult的枚舉常量及其說明

枚舉常量描述
CONTINUE繼續(xù)處理
SKIP_SIBLINGS繼續(xù)處理而不訪問文件或目錄的兄弟節(jié)點。
SKIP_SUBTREE繼續(xù)處理,而不訪問目錄中的條目。
TERMINATE終止文件訪問過程。

我們不需要在我們的文件訪問類的所有四個方法中編寫邏輯。要復制目錄,請使用preVisitDirectory()方法來創(chuàng)建一個新目錄和visitFile()方法來復制文件。

以下代碼顯示如何打印目錄的子目錄和文件的名稱。

import static java.nio.file.FileVisitResult.CONTINUE;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class Main {
  public static void main(String[] args) {
    Path startDir = Paths.get("");
    FileVisitor<Path> visitor = getFileVisitor();
    try {
      Files.walkFileTree(startDir, visitor);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  public static FileVisitor<Path> getFileVisitor() {
    class DirVisitor<Path> extends SimpleFileVisitor<Path> {
      @Override
      public FileVisitResult preVisitDirectory(Path dir,
          BasicFileAttributes attrs) {

        System.out.format("%s [Directory]%n", dir);
        return CONTINUE;
      }

      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
        System.out.format("%s [File,  Size: %s  bytes]%n", file, attrs.size());
        return CONTINUE;
      }
    }
    FileVisitor<Path> visitor = new DirVisitor<>();
    return visitor;
  }
}

上面的代碼生成以下結(jié)果。

例子

以下代碼顯示如何使用FileVisitor API刪除目錄樹。

import static java.nio.file.FileVisitResult.CONTINUE;
import static java.nio.file.FileVisitResult.TERMINATE;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class Main {
  public static void main(String[] args) {
    Path dirToDelete = Paths.get("DIR");
    FileVisitor<Path> visitor = getFileVisitor();

    try {
      Files.walkFileTree(dirToDelete, visitor);
    }
    catch (IOException e) {
      System.out.println(e.getMessage());
    }
  }

  public static FileVisitor<Path> getFileVisitor() {

    class DeleteDirVisitor extends SimpleFileVisitor<Path> {
      @Override
      public FileVisitResult postVisitDirectory(Path dir, IOException e)
          throws IOException {
        FileVisitResult result = CONTINUE;
        if (e != null) {
          System.out.format("Error deleting  %s.  %s%n", dir, e.getMessage());
          result = TERMINATE;
        } else {
          Files.delete(dir);
          System.out.format("Deleted directory  %s%n", dir);
        }
        return result;
      }

      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throws IOException {
        Files.delete(file);
        System.out.format("Deleted file %s%n", file);
        return CONTINUE;
      }
    }
    FileVisitor<Path> visitor = new DeleteDirVisitor();
    return visitor;
  }
}

上面的代碼生成以下結(jié)果。


例2

以下代碼顯示如何使用walkFileTree()方法跟隨符號鏈接。

import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.EnumSet;
import java.util.Set;
import static  java.nio.file.FileVisitOption.FOLLOW_LINKS;
public class Main {
  public static void main(String[] args) throws Exception {
    Path startDir = Paths.get("");
    FileVisitor<Path> visitor = create your visitor;

    Set<FileVisitOption> options = EnumSet.of(FOLLOW_LINKS);

    int depth = Integer.MAX_VALUE;

    Files.walkFileTree(startDir, options, depth, visitor);
  }
}

模式匹配

我們可以使用glob和正則表達式模式對字符串形式的Path對象執(zhí)行模式匹配。

功能接口PathMatcher用于執(zhí)行匹配。它包含一個方法matches(Path path)方法,如果指定的路徑匹配模式,則該方法返回true。

模式字符串由兩部分組成,語法和模式由冒號分隔:

syntax:pattern

語法的值是glob或regex。模式部分遵循取決于語法部分的值的語法。

glob模式使用以下語法規(guī)則:

  • * 匹配零個或多個字符,而不會交叉目錄邊界。
  • ** 匹配零個或多個字符跨目錄邊界。
  • ? 只匹配一個字符。
  • \ 轉(zhuǎn)義以下字符的特殊含義。
  • \\ 匹配單個反斜杠。
  • \* 匹配星號。

放在括號 [] 中的字符稱為括號表達式,它匹配單字符。[aeiou]匹配a,e,i,o或u。

兩個字符之間的破折號指定范圍。[a-z]匹配a和z之間的所有字母。

左括號后的感嘆號(!)被視為否定。[!abc]匹配除a,b和c之外的所有字符。

通過在大括號({})中指定逗號分隔的子模式來使用一組子模式。例如,{txt,java,doc}匹配txt,java和doc。

路徑的根組件的匹配是實現(xiàn)相關(guān)的。

以下代碼顯示了如何使用PathMatcher對象將路徑與glob模式匹配。

import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;

public class Main {
  public static void main(String[] args) {
    String globPattern = "glob:**txt";
    PathMatcher matcher = FileSystems.getDefault().getPathMatcher(globPattern);
    Path path = Paths.get("C:\\Java_Dev\\test1.txt");
    boolean matched = matcher.matches(path);
    System.out.format("%s matches  %s:  %b%n", globPattern, path, matched);
  }
}

上面的代碼生成以下結(jié)果。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號