Nio2
什么是Java Nio2,java Nio2是在java 7新增内容,在java1.4 nio的基础上再次对I/O模型的增强,新增Path类,Files工具类,Paths工具类,主要是为了方便文件、目录的操作。
java.nio.file.Path
一个Path代表了一个在本地文件系统的一个路径
1.创建一个path类
/**
* 创建一个Path类
*
* @throws URISyntaxException
*/
private static void createPath() throws URISyntaxException {
//1.根据文件名构建
Path path = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test\\test.txt");
System.out.println(path);
//2.根据多个文件名,子文件名构建
Path path1 = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test", "sub", "subTest.txt");
System.out.println(path1);
//3.根据统一资源定位符构建
Path path2 = Paths.get(new URI("file:///C:/Users/baopz/Desktop/图片/test/uri.txt"));
System.out.println(path2);
//4.根据FileSystems创建
Path path3 = FileSystems.getDefault().getPath("C:", "1.txt");
System.out.println(path3);
}
2.Path对象和File相互转换 Path对象转换为URI
/**
* Path对象和文件相互转换
* path转换为uri
*/
public static void convert() {
//path转换为文件
Path path = Paths.get("c://1.txt");
System.out.println(path);
File file = path.toFile();
System.out.println(file.getAbsolutePath());
//文件转换为path
File file1 = new File("C://1.txt");
System.out.println(file1);
Path path1 = file1.toPath();
System.out.println(path1);
//path转换为uri
URI uri = path1.toUri();
System.out.println(uri);
}
3.创建孩子节点,创建兄弟节点
/**
* 创建孩子节点,创建兄弟节点
*/
public static void resolve() {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test");
//创建孩子节点
Path child = current.resolve("child");
System.out.println(child);
//创建兄弟节点
Path brother = current.resolveSibling("brother");
System.out.println(brother);
}
4.得到文件名,以及Path类的计算操作
/**
* path结构,root/0/1/2/..,count不会计算root层,根节点的parent是null
* 截取部分subPath [start,end),包含start的下标,不包含end的下标
*/
public static void getFilename() {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test\\1.txt");
Path filename = current.getFileName();
System.out.println(filename.toString());
//根据计算得到文件名
filename = current.getName(current.getNameCount() - 1);
System.out.println(filename.toString());
//得到根节点
System.out.println(current.getRoot());
//打印每一层的filename
for (int i = 0; i < current.getNameCount(); i++) {
System.out.println(i + "层 " + current.getName(i));
}
//根节点的父亲节点是null
System.out.println(current.getRoot().getParent());
//截取部分path[start,end)
System.out.println(current.subpath(1,3));
//是不是以1.txt结尾的path,注意这里不能用来判断是不是某种格式结尾,这里计算的最后一个节点
//这里返回的是true
System.out.println(current.endsWith("1.txt"));
//这里返回的是false
System.out.println(current.endsWith(".txt"));
}
5.regex或者glob匹配
/**
* regex或者glob匹配
* 匹配语法
* 语法:模式 => {regex|glob}:pattern
*/
public static void match() {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test\\1.txt");
FileSystem fileSystem = FileSystems.getDefault();
//正则表达式匹配.txt结尾
PathMatcher pathMatcher = fileSystem.getPathMatcher("regex:.*.txt");
System.out.println(pathMatcher.matches(current));
//glob匹配.txt结尾
pathMatcher = fileSystem.getPathMatcher("glob:*.txt");
System.out.println(pathMatcher.matches(current));
}
6.java.nio.file.WatchService监控器
这个功能还是非常实用的,文件监控器,可以监控文件以及目录的变化,以及设置监控频率,这里是演示,会运行在main线程里面,项目中建议开个线程单独运行,(后面我会吧线程的相关操作列出来)。
/**
* 文件监控器,可以监控文件以及目录的变化,以及设置监控频率
*/
public static void watchServer() throws IOException, InterruptedException {
FileSystem fileSystem = FileSystems.getDefault();
WatchService watchService = fileSystem.newWatchService();
Path path = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test");
//监控事件,新增,修改,删除,溢出,监控频率=low
path.register(watchService,new WatchEvent.Kind<?>[]{StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.OVERFLOW},
SensitivityWatchEventModifier.LOW);
while (true) {
WatchKey watchKey = watchService.take();
for (WatchEvent<?> watchEvent : watchKey.pollEvents()) {
//有新文件创建
if (watchEvent.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
Path path1 = (Path) watchEvent.context();
System.out.println("新建了一个文件:" + path1);
}
//有文件被删除
if(watchEvent.kind()==StandardWatchEventKinds.ENTRY_DELETE){
Path path1 = (Path) watchEvent.context();
System.out.println("删除了一个文件:" + path1);
}
if (watchEvent.kind()==StandardWatchEventKinds.ENTRY_MODIFY){
Path path1 = (Path) watchEvent.context();
System.out.println("文件被修改:"+path1);
}
if (watchEvent.kind()==StandardWatchEventKinds.OVERFLOW){
System.out.println("溢出");
}
}
boolean valid = watchKey.reset();
if (!valid) {
break;
}
}
}
java.nio.file.Files、java.nio.file.FileSystems工具类
1.创建文件
public static void createFile() throws IOException {
Path path = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test\\test.txt");
//得到上一层节点
Path parent = path.getParent();
if (Files.notExists(parent)) {
Files.createDirectories(parent);
}
//在创建文件的时候,一定要先存着上一层的目录
if (Files.notExists(path)) {
Files.createFile(path);
}
}
2.删除文件
public static void delete() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test\\1.txt");
boolean isSuccess = Files.deleteIfExists(current);
System.out.println(isSuccess);
}
3.得到BufferedReader,进行字符操作
/**
* 字符集对应不上会抛错
* @throws IOException
*/
public static void readBuffer() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test\\1.txt");
BufferedReader bufferedReader = Files.newBufferedReader(current, Charset.forName("gbk"));
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
}
4.列出当前文件夹下所有文件
/**
* 列出当前目录下所有文件
* @throws IOException
*/
public static void listFile() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test");
DirectoryStream directoryStream = Files.newDirectoryStream(current);
for (Object aDirectoryStream : directoryStream) {
System.out.println(aDirectoryStream);
}
}
5.树遍历
public static void walkingTheFileTree() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test");
Set<FileVisitOption> visitOptions = new HashSet<>();
visitOptions.add(FileVisitOption.FOLLOW_LINKS);
//设置开始节点,访问操作,最大访问深度,具体访问操作
Files.walkFileTree(current, visitOptions, 3, new MyFileVisitor());
}
public static class MyFileVisitor implements FileVisitor<Path> {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.println("访问文件夹之前操作。" + dir);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("访问当前文件:" + file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
System.out.println("访问文件错误:" + file);
//跳过sub
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
System.out.println("访问文件夹之后操作:" + dir);
return FileVisitResult.CONTINUE;
}
}
6.文件属性,以及文件操作
public static void accessFile() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\图片\\test");
FileSystem fileSystem = FileSystems.getDefault();
//遍历文件支持的所有视图
for (String s : fileSystem.supportedFileAttributeViews()) {
System.out.println(s);
}
//basic视图
BasicFileAttributes basicFileAttributes = Files.readAttributes(current,BasicFileAttributes.class);
System.out.println(basicFileAttributes.lastModifiedTime());
//dos视图
DosFileAttributes dosFileAttributes = Files.readAttributes(current,DosFileAttributes.class);
System.out.println(dosFileAttributes.isHidden());
//复制
Files.copy(current,current.resolve("副本"));
}
到目前为止,java1.7 的Nio2已经写完了,接下来会讲解关于网络通信,还有一个异步通道会在下一章开头讲,会提一下Netty,再之后会针对Netty做专题详细讲解。