FileVisitor API可以遞歸地處理文件樹中的所有文件和目錄。
當我們要對文件樹中的所有或某些文件或目錄執(zhí)行某些操作時,F(xiàn)ileVisitor API非常有用。
SimpleFileVisitor類是FileVisitor接口的基本實現(xiàn)。
當訪問文件/目錄時,SimpleFileVisitor類不執(zhí)行任何操作。我們可以從SimpleFileVisitor類繼承我們的文件訪問類,并且只覆蓋適合我們需要的方法。
FileVisitor接口的方法:
ID | 含義 |
---|---|
1 | FileVisitResult preVisitDirectory(T dir,BasicFileAttributes attrs) 在訪問目錄中的條目之前調(diào)用一次。 |
2 | FileVisitResult postVisitDirectory(T dir,IOException exc) 已訪問目錄中的后調(diào)用項。如果在目錄的迭代期間拋出了任何異常,則將異常對象作為第二個參數(shù)傳遞給此方法。如果此方法的第二個參數(shù)為null,則在目錄迭代期間沒有異常。 |
3 | FileVisitResult visitFile(T文件,BasicFileAttributes attrs) 當訪問目錄中的文件時調(diào)用。 |
4 | FileVisitResult 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é)果。
以下代碼顯示如何使用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ī)則:
放在括號 []
中的字符稱為括號表達式,它匹配單字符。[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é)果。
更多建議: