• 【Java基础 】Java7 NIO Files,Path 操作文件


    从Java1.0到1.3,我们在开发需要I/O支持的应用时,要面临以下问题:

    • 没有数据缓冲区或通道的概念,开发人员要编程处理很多底层细节
    • I/O操作会被阻塞,扩展能力有限
    • 所支持的字符集编码有限,需要进行很多手工编码工作来支持特定类型的硬件。
    • 不支持正则表达式,数据处理困难。

    为了解决这些问题,在Java1.4引入了NIO。其中有两次主要改进:

    • 在Java1.4中引入非阻塞I/O
    • 在Java7中对非阻塞I/O进行修改

    自此Java为I/O操作抽象出了缓冲区和通道区;字符集的编码和解码能力;提供了能够将文件映射为内存数据的接口;实现非阻塞I/O的能力;基于流行的Perl实现的正则表达式类库。

    NIO使Java向前迈出了一大步,但I/O编程对于开发人员来说仍然是个挑战,特别是对于文件和目录而言,支持力度还是不够。为了突破这些局限性,在Java7中提供了NIO.2 API。它有三个目标:

    • 一个能批量获取文件属性的文件系统接口,引入标准文件系统实现的服务提供者接口
    • 提供一个套接字和文件都能够进行异步
    • 完成JSR-51中定义的套接字--通道功能,包括额外对绑定、选项配置和多播数据报的支持。

    Path:通常代表文件系统中的位置。

    1. 创建一个Path

      Path path1 = Paths.get("D:\test\test1"); // 等同 Path path1 = FileSystems.getDefault().getPath("D:\test");
      
    2. 从Path中获取信息

      我们可以从Path中获取信息,比如其父目录,文件名等...

      System.out.println("fileName : " + path1.getFileName()); // 获取文件名称
      System.out.println("number of name elements : " + path1.getNameCount()); // 获取名称元素的数量
      System.out.println("parent path : " + path1.getParent());
      System.out.println("root of path : " + path1.getRoot());
      System.out.println("subpath from root, 2 elements deep : " + path1.subpath(0, 2)); // 获取第0-2个元素之间的子路径
      
    3. NIO.2 Path和Java已有的FIle类

      新API中的类可以完全替代过去基于java.io.File的API。但是我们不可避免的要和大量遗留下来的I/O代码交互。Java7提供了两个新方法:

      • java.io.File类中新增了toPath()方法,可以把已有的File转化为新的Path
      • Path类有个toFile()方法,它可以把已有的Path转为File
      File file = new File("D:\test");
      Path path3 = file.toPath(); // file to path
      path3.toAbsolutePath();
      file = path3.toFile(); // path to file
      
    4. 在目录中查找文件

      先来一个简单的例子,用匹配模式过滤出当前目录下所有的.txt和.jpg文件。这是处理单个目录的能力。

      Path path4 = Paths.get("D:\test");
      
      DirectoryStream<Path> stream = Files.newDirectoryStream(path4, "*.{txt,jpg}"); // 声明过滤流,匹配模式为glob模式匹配
      for (Path entry : stream) {
          System.out.println(entry.getFileName());
      }
      
    5. 遍历目录树

      Java7支持整个目录树的遍历。也就是说我们可以很容易的搜索目录树中的文件,在子目录中查找,并对它们执行操作。

      Path path5 = Paths.get("F:\test\demo"); // 设置起始目录
      Files.walkFileTree(path5, new FindJavaVisitor()); // 关键方法
      
      private static class FindJavaVisitor extends SimpleFileVisitor<Path> {
          // SimpleFileVisitor可以完成大部分工作,比如遍历目录。我们唯一要做的就是重写visitFile()这个方法。
          @Override
          public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
              if (file.toString().endsWith(".java")) {
                  System.out.println(file.getFileName());
              }
              return FileVisitResult.CONTINUE;
          }
      }
      

    Files:让我们轻松复制,移动,删除或处理文件的工具类,有我们需要的所有方法。

    1. 创建和删除文件

      Path path6 = Paths.get("D:\backup\test.txt");
      Files.createFile(path6); // 创建文件,要保证D:\backup存在
      Files.delete(path6);
      
    2. 文件的复制和移动

      Path sourcePath7 = Paths.get("D:\test\test.txt");
      Path targetPath7 = Paths.get("D:\backup\test.txt");
      Files.copy(sourcePath7, targetPath7, StandardCopyOption.REPLACE_EXISTING); // REPLACE_EXISTING 覆盖即替换已有文件
      Files.move(sourcePath7, targetPath7, StandardCopyOption.REPLACE_EXISTING);
      
    3. 文件的属性

      Path path8 = Paths.get("D:\test");
      System.out.println(Files.getLastModifiedTime(path8));
      System.out.println(Files.size(path8));
      System.out.println(Files.isSymbolicLink(path8));
      System.out.println(Files.isDirectory(path8));
      System.out.println(Files.readAttributes(path8, "*")); // 获取文件所有的属性
      
    4. 快速读写数据

      Java7可以尽可能多的提供用来的读取和写入文件内容的辅助方法。
      当然这些新方法使用Path,但它们也可以与那些java.io包里基于流的类进行互相操作。因此我们用一个方法就可以读取文件中的所有行或全部字节。

      // Java7可以直接用缓冲区的读取器和写入器或输入输出流(为了和以前的Java I/O代码兼容)打开文件。
      BufferedWriter writer = Files.newBufferedWriter(path9, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
      writer.write("Hello world...");
      writer.flush();
      writer.close();
      
      BufferedReader reader = Files.newBufferedReader(path9, StandardCharsets.UTF_8);
      String line;
      while ((line = reader.readLine()) != null) {
          System.out.println(line);
      }
      
      // 简化读取和写入
      
      List<String> lines = Files.readAllLines(path9, StandardCharsets.UTF_8);
      for (String line1 : lines) {
          System.out.println(line1);
      }
      
      byte[] bytes = Files.readAllBytes(path9); // 读取文件字节流
      System.out.println(new String(bytes, StandardCharsets.UTF_8));
      
      Files.write(path9, bytes); // 写入文件字节流
      

      以前读写文件都比较麻烦,用Java7的NIO之后是不是非常方便呢?

    参考内容:《Java程序员修炼之道》

  • 相关阅读:
    浅析Python模块的引入和调用
    一篇文章带你了解CSS定位知识
    盘点4大下载神器,教你分分钟搞定文件下载
    Mysql查询语句进阶知识集锦
    (原创)高DPI适配经验系列:(四)高DPI适配示例
    (原创)高DPI适配经验系列:(三)字体与字号、缩放锚点
    (原创)IconFont(矢量图标字体)在Winform中的应用
    (原创)高DPI适配经验系列:(二)按DPI范围适配
    (原创)高DPI适配经验系列:(一)缩放比例与DPI对应关系
    [C#] (原创)一步一步教你自定义控件——06,MaskLayer(遮罩层)
  • 原文地址:https://www.cnblogs.com/lebo0425/p/6649060.html
Copyright © 2020-2023  润新知