Java NIO.2
- NIO.2
- Path, Paths, Files
- FileVisitor
- WatchService
- 檔案屬性
NIO.2
Java7 對NIO進行了改進:
- 新增
包,提供全面的檔案IO和檔案系統通路;java.nio.file
- 基于異步Channel的IO,在
下增加 Asynchronous開頭的Channel接口和類。java.nio.channels
Path, Paths, Files
NIO.2 引入Path接口。代表平台無關的路徑。
增加了 Files 和 Paths 兩個工具類。
Path path = Paths.get(".");
//包含路徑名的數量
System.out.println(path.getNameCount());
// null
System.out.println(path.getRoot());
//絕對路徑
Path absolutePath = path.toAbsolutePath();
System.out.println(absolutePath);
System.out.println(absolutePath.getRoot());
System.out.println(absolutePath.getNameCount());
//多個連接配接路徑
Path path1 = Paths.get("/", "Users", "data");
System.out.println(path1);
Files工具類, 操作檔案
//複制檔案
Path path2 = Paths.get("abc.txt");
Files.copy(path2, new FileOutputStream("abc2.txt"));
//是否為隐藏檔案
System.out.println(Files.isHidden(path2));
//讀取檔案所有行
List<String> lines = Files.readAllLines(path2, Charset.forName("utf-8"));
System.out.println(lines);
//檔案大小
System.out.println(Files.size(path2));
//寫入檔案
List<String> list = new ArrayList<>();
list.add("張三");
list.add("李四");
Files.write(Paths.get("name.txt"), list, Charset.forName("utf-8"));
//使用Stream API
Files.list(Paths.get(".")).forEach(path3 -> System.out.println(path3));
Files.lines(path2, Charset.forName("utf-8")).forEach(line -> System.out.println(line));
//磁盤空間
FileStore fileStore = Files.getFileStore(path2);
System.out.println(fileStore.getTotalSpace());
System.out.println(fileStore.getUsableSpace());
FileVisitor
Files工具類提供了周遊檔案和目錄的方法:
walkFileTree(): 周遊檔案和子目錄, 可以設定maxDepth深度。
需要 FileVisitor參數,代表一個檔案通路器。
FileVisitor 中定義下面方法:
- postVisitDirectory(): 通路子目錄後觸發
- preVisitDirectory():通路子目錄前
- visitFile() : 通路檔案時觸發
-
visitFileFailed(): 通路檔案失敗觸發
這四個方法都傳回 FileVisitResult 對象, 是一個枚舉類, 代表後續行為:
- CONTINUE: 繼續
- SKIP_SIBLINGS: 繼續, 但不放問兄弟檔案或目錄
- SKIP_SUBTREE: 繼續, 但不放問子目錄樹
- TERMINATE: 中支
Files.walkFileTree(Paths.get("."), new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("visit :" + file);
if (file.endsWith("FliesTest.java")){
System.out.println("found it");
return FileVisitResult.TERMINATE;
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.println("visit DIR: " + dir);
return FileVisitResult.CONTINUE;
}
});
WatchService
NIO.2的 Path 類提供一個監聽檔案系統的變化。
register(WatchService watcher, WatchEvent)
WatchService 代表監聽服務。
注冊完調用下面方法擷取監聽檔案的變化:
- poll(): 擷取下一個WatchKey, 可以設定等待時間
- take():擷取下一個WatchKey, 沒有就一直等待
WatchService watchService = FileSystems.getDefault().newWatchService();
Paths.get(".").register(watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE);
//死循環
while (true){
//擷取下一個watchkey, 沒有就等待
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()){
System.out.println(event.context() + " : " + event.kind());
}
//重設WatchKey
boolean valid = key.reset();
if(!valid){
break;
}
}
檔案屬性
NIO.2在 java.nio.file.attribute下提供了大量工具類, 用于處理檔案的屬性。
XxxAttributeView : 檔案屬性視圖
XxxAttributes: 檔案屬性集合。
FileAttributeView 接口下面的父接口:
AclFileAttributeView: 檔案的ACL權限資訊 Access Control List
BasicFileAttributeView: 基本屬性
DosFileAttributeView : DOS相關屬性, 是否隻讀, 隐藏,系統檔案,
FileOwnerFileAttributeView: 檔案所有者
PosixFileAttributeView: 修改檔案所有者,組所有者,通路權限, 同Linux的 chmod 指令
UserDefinedFileAttributeView: 自定義屬性
Path path2 = Paths.get("abc.txt");
//基本屬性
BasicFileAttributeView view = Files.getFileAttributeView(path2, BasicFileAttributeView.class);
BasicFileAttributes attributes = view.readAttributes();
//建立時間
System.out.println(new Date(attributes.creationTime().toMillis()));
//最後通路時間
System.out.println(new Date(attributes.lastAccessTime().toMillis()));
//最後修改時間
System.out.println(new Date(attributes.lastModifiedTime().toMillis()));
//檔案大小
System.out.println(attributes.size());
//檔案owner資訊
FileOwnerAttributeView ownerAttributeView = Files.getFileAttributeView(path2, FileOwnerAttributeView.class);
System.out.println(ownerAttributeView.getOwner());
UserPrincipal user = FileSystems.getDefault()
.getUserPrincipalLookupService().lookupPrincipalByName("zhangsan");
ownerAttributeView.setOwner(user);
//自定義屬性
UserDefinedFileAttributeView defineView = Files.getFileAttributeView(path2, UserDefinedFileAttributeView.class);
List<String> attNames = defineView.list();
for(String name : attNames){
ByteBuffer byteBuffer = ByteBuffer.allocate(defineView.size(name));
defineView.read(name, byteBuffer);
byteBuffer.flip();
String value = Charset.defaultCharset().decode(byteBuffer).toString();
System.out.println(name + " : " + value);
}
//添加自定義屬性
defineView.write("作者", Charset.defaultCharset().encode("張三"));
//檔案Dos屬性
DosFileAttributeView dosView = Files.getFileAttributeView(path2, DosFileAttributeView.class);
dosView.setHidden(true);
dosView.setReadOnly(true);