java核心学习(二十) javaNIO.2

一、Path、Paths、Files核心API

  Path接口代表一个平台无关的路径,Files类包含了大量静态的工具方法来操纵文件;Paths则包含了两个返回Path的静态工厂方法。下面试一试

  

package NIOTest;

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

public class PathTest {
    public static void main(String[] args) throws Exception{
        Path path = Paths.get(".");
        System.out.println("path里包含的路径数量:"+ path.getNameCount());
        System.out.println("path的根路径:" + path.getRoot());
        Path absolutePath = path.toAbsolutePath();
        System.out.println(absolutePath);
        System.out.println("absolutePath的根路径为:"+ absolutePath.getRoot());
        System.out.println("absolutePath里包含的路径数量:" + absolutePath.getNameCount());
        System.out.println(absolutePath.getName(3));
        Path path2 = Paths.get("g:","xx","ll");
        System.out.println(path2);
    }
}

  输出为

path里包含的路径数量:1
path的根路径:null
E:\app\talkroom2\WhhTalkRoom_server\.
absolutePath的根路径为:E:\
absolutePath里包含的路径数量:4
.
g:\xx\ll

Process finished with exit code 0
  getNameCount()方法返回Path路径所包含的路径名的数量。

接下来的例子展示Files工具类的用法,这个工具类高度封装了文件的各种操作,极其强大。
package NIOTest;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class FilesTest {
    public static void main(String[] args) {
        try {
            Path path = Files.copy(Paths.get("./src/main/java/NIOTest/FilesTest.java"), Paths.get("a.txt"));
            System.out.println(path.toString());
            System.out.println("FilesTest.java是否为隐藏问件:" + Files.isHidden(Paths.get("./src/main/java/NIOTest/FilesTest.java")));
            //一次性读取FilesTest.java的所有行
            List<String> lines = Files.readAllLines(Paths.get("./src/main/java/NIOTest/FilesTest.java"), Charset.forName("UTF-8"));
            System.out.println(lines);
            //判断指定文件大小
            System.out.println("FilesTest.java的大小为:" + Files.size(Paths.get("./src/main/java/NIOTest/FilesTest.java")));
            List<String> poem = new ArrayList<>();
            poem.add("水晶潭底银鱼跃");
            poem.add("清徐风中碧竿横");
            Files.write(Paths.get("poem.txt"), poem, Charset.forName("UTF-8"));

            //java8进一步增强了Files工具类的功能,允许开发者使用StreamAPI来操作文件目录和文件内容
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

  输出

a.txt
FilesTest.java是否为隐藏问件:false
[package NIOTest;, , import java.io.File;, import java.io.IOException;, import java.nio.charset.Charset;, import java.nio.file.Files;, import java.nio.file.Path;, import java.nio.file.Paths;, import java.util.ArrayList;, import java.util.List;, , public class FilesTest {,     public static void main(String[] args) {,         try {,             Path path = Files.copy(Paths.get("./src/main/java/NIOTest/FilesTest.java"), Paths.get("a.txt"));,             System.out.println(path.toString());,             System.out.println("FilesTest.java是否为隐藏问件:" + Files.isHidden(Paths.get("./src/main/java/NIOTest/FilesTest.java")));,             //一次性读取FilesTest.java的所有行,             List<String> lines = Files.readAllLines(Paths.get("./src/main/java/NIOTest/FilesTest.java"), Charset.forName("UTF-8"));,             System.out.println(lines);,             //判断指定文件大小,             System.out.println("FilesTest.java的大小为:" + Files.size(Paths.get("./src/main/java/NIOTest/FilesTest.java")));,             List<String> poem = new ArrayList<>();,             poem.add("水晶潭底银鱼跃");,             poem.add("清徐风中碧竿横");,             Files.write(Paths.get("poem.txt"), poem, Charset.forName("UTF-8"));, ,             //java8进一步增强了Files工具类的功能,允许开发者使用StreamAPI来操作文件目录和文件内容,         } catch (IOException ioe) {,             ioe.printStackTrace();,         },     }, }]
FilesTest.java的大小为:1496

Process finished with exit code 
关于StreamAPI,请移步这里:Java 8 中的 Streams API 详解


二、使用FileVisitor遍历文件和目录
  Files工具类提供了如下两个房啊来遍历文件和子目录
    walkFileTree(Path start,FileVisitor<? super Path> vistor) :遍历start路径下的所有文件和子目录
    walkFileTree(Path start , Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor): 上一个方法的重载方法
,最多遍历maxDepth深度的文件。
  上面两个方法需要的FileVisitor接口的实例是一个文件访问器,walkFileTree()方法会自动遍历start路径下的文件和子目录,遍历每一个文件和子目录都会调用FileVisitor
中相应的方法。
  

 

 


package NIOTest;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class FileVisitorTest {
    public static void main(String[] args) throws IOException{
        Files.walkFileTree(Paths.get(".").toAbsolutePath(),new SimpleFileVisitor<Path>(){
            //访问文件时触发
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println("正在访问"+file+"文件");
                if(file.endsWith("FileVisitorTest.java")){
                    System.out.println("---已找到目标文件---");
                    return FileVisitResult.TERMINATE;
                }
                return FileVisitResult.CONTINUE;
            }
            //访问目录时触发
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                System.out.println("正在访问:"+ dir +"路径");
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

 




三、使用WatchService监控文件变化
  在之前的java版本中若要监控文件变化则需要启动一个后台线程,写一个定时任务来检查文件是否改变。
  Path类提供了如下一个方法来监听文件系统的变化
    register(WathcService watcher,WatchEvent.Kind<?>...events)用watcher监听该path代表的目录下的文件变化,events参数指定要监听哪些类型的变化。
  看程序
  
package NIOTest;

import org.apache.xmlbeans.impl.store.Path;

import java.io.IOException;
import java.nio.file.*;

public class WatchServiceTest {
    public static void main(String[] args) throws Exception{
        //WatchService代表一个文件系统监听服务,获取文件系统的WatchService对象
        WatchService watchService = FileSystems.getDefault().newWatchService();
        //调用Path提供的register为该目录注册文件监听服务和监听事件
        Paths.get("C:/").register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE,
                StandardWatchEventKinds.ENTRY_MODIFY);
        //使用一个死循环来重复获取文件变化
        while (true){
            //获取下一个文件变化事件
            WatchKey key = watchService.take();
            for (WatchEvent<?> event : key.pollEvents())
            {
                System.out.println(event.context() + "文件发生了"+ event.kind() + "事件");
            }
            //重设WatchKey
            boolean valid = key.reset();
            //重设失败退出监听
            if(!valid){
                break;
            }
        }
    }
}
在获取文件变化事件时有三种方法:

 

四、访问文件属性
  java.nio.file.attribute包下提供大量工具类来读取、修改文件属性,用到的时候再查阅。
posted @ 2017-09-18 15:27  The_shy  阅读(275)  评论(0编辑  收藏  举报