NIO.2
Java7 对NIO进行了改进:
- 新增
java.nio.file
包,提供全面的文件IO和文件系统访问; - 基于异步Channel的IO,在
java.nio.channels
下增加 Asynchronous开头的Channel接口和类。
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);