zoukankan      html  css  js  c++  java
  • 【Java】Java NIO Path和Files(五)

    一、文件I/O基石:Path

      Java7中文件IO发生了很大的变化,专门引入了很多新的类来取代原来的基于java.io.File的文件IO操作方式:

    import java.nio.file.DirectoryStream;
    import java.nio.file.FileSystem;
    import java.nio.file.FileSystems;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.nio.file.attribute.FileAttribute;
    import java.nio.file.attribute.PosixFilePermission;
    import java.nio.file.attribute.PosixFilePermissions;·
    
    ......等等

      我们将从下面几个方面来学习Path类:
      - 创建一个Path
      - File和Path之间的转换,File和URI之间的转换
      - 获取Path的相关信息
      - 移除Path中的冗余项

    1.1、创建一个Path

      创建Path实例可以通过 Paths工具类 的 get()方法:

    1 //使用绝对路径
    2 Path path= Paths.get("c:\data\myfile.txt");
    1 //使用相对路径
    2 Path path = Paths.get("/home/jakobjenkov/myfile.txt");

      下面这种创建方式和上面等效:

    1 Path path = FileSystems.getDefault().getPath("c:\data\myfile.txt");

    1.2、File和Path之间的转换,File和URI之间的转换

    1 File file = new File("C:/my.ini");
    2 Path p1 = file.toPath();
    3 p1.toFile();
    4 file.toURI();

    1.3、获取Path的相关信息

     1 //使用Paths工具类的get()方法创建
     2 Path path = Paths.get("D:\XMind\bcl-java.txt");
     3 /*        //使用FileSystems工具类创建
     4 Path path2 = FileSystems.getDefault().getPath("c:\data\myfile.txt");*/
     5 System.out.println("文件名:" + path.getFileName());
     6 System.out.println("名称元素的数量:" + path.getNameCount());
     7 System.out.println("父路径:" + path.getParent());
     8 System.out.println("根路径:" + path.getRoot());
     9 System.out.println("是否是绝对路径:" + path.isAbsolute());
    10 //startsWith()方法的参数既可以是字符串也可以是Path对象
    11 System.out.println("是否是以为给定的路径D:开始:" + path.startsWith("D:\") );
    12 System.out.println("该路径的字符串形式:" + path.toString());

      结果:

    文件名:bcl-java.txt
    名称元素的数量:2
    父路径:D:XMind
    根路径:D:
    是否是绝对路径:true
    是否是以为给定的路径D:开始:true
    该路径的字符串形式:D:XMindcl-java.txt

    1.4、移除冗余项

      某些时候在我们需要处理的Path路径中可能会有一个或两个点

      - .表示的是当前目录
      - ..表示父目录或者说是上一级目录:

      下面通过实例来演示一下使用Path类的normalize()和toRealPath()方法把.和..去除。

      • normalize() : 返回一个路径,该路径是冗余名称元素的消除。
      • toRealPath() : 融合了toAbsolutePath()方法和normalize()方法
     1 //.表示的是当前目录
     2 Path currentDir = Paths.get(".");
     3 System.out.println(currentDir.toAbsolutePath());//输出C:UsersAdministratorNIODemo.
     4 Path currentDir2 = Paths.get(".\NIODemo.iml");
     5 System.out.println("原始路径格式:"+currentDir2.toAbsolutePath());
     6 System.out.println("执行normalize()方法之后:"+currentDir2.toAbsolutePath().normalize());
     7 System.out.println("执行toRealPath()方法之后:"+currentDir2.toRealPath());
     8 
     9 //..表示父目录或者说是上一级目录:
    10 Path currentDir3 = Paths.get("..");
    11 System.out.println("原始路径格式:"+currentDir3.toAbsolutePath());
    12 System.out.println("执行normalize()方法之后:"+currentDir3.toAbsolutePath().normalize());
    13 System.out.println("执行toRealPath()方法之后:"+currentDir3.toRealPath());

      结果:

    C:UsersAdministratorNIODemo.
    原始路径格式:C:UsersAdministratorNIODemo.NIODemo.iml
    执行normalize()方法之后:C:UsersAdministratorNIODemoNIODemo.iml
    执行toRealPath()方法之后:C:UsersAdministratorNIODemoNIODemo.iml
    原始路径格式:C:UsersAdministratorNIODemo..
    执行normalize()方法之后:C:UsersAdministrator
    执行toRealPath()方法之后:C:UsersAdministrator

    二、Files工具类

      Java NIO中的Files类(java.nio.file.Files)提供了多种操作文件系统中文件的方法。本节教程将覆盖大部分方法。Files类包含了很多方法,所以如果本文没有提到的你也可以直接查询JavaDoc文档。

    java.nio.file.Files类是和java.nio.file.Path相结合使用的 

    2.1、检查给定的Path在文件系统中是否存在

      通过 Files.exists() 检测文件路径是否存在:

    1 Path path = Paths.get("D:\XMind\bcl-java.txt");
    2 
    3 boolean pathExists = Files.exists(path, new LinkOption[]{LinkOption.NOFOLLOW_LINKS});
    4 
    5 System.out.println(pathExists);//true

      注意Files.exists()的的第二个参数。它是一个数组,这个参数直接影响到Files.exists()如何确定一个路径是否存在。在本例中,这个数组内包含了LinkOptions.NOFOLLOW_LINKS,表示检测时不包含符号链接文件。

    2.2、创建文件/文件夹

    • 创建文件:

      通过 Files.createFile() 创建文件,

    1 Path target2 = Paths.get("C:\mystuff.txt");
    2 try {
    3     if(!Files.exists(target2))
    4         Files.createFile(target2);
    5 } catch (IOException e) {
    6     e.printStackTrace();
    7 }
    • 创建文件夹:

      • 通过 Files.createDirectory() 创建文件夹
      • 通过 Files.createDirectories() 创建文件夹

      Files.createDirectories()会首先创建所有不存在的父目录来创建目录,而Files.createDirectory()方法只是创建目录,如果它的上级目录不存在就会报错。比如下面的程序使用Files.createDirectory() 方法创建就会报错,这是因为我的D盘下没有data文件夹,加入存在data文件夹的话则没问题。

     1 Path path = Paths.get("D://data//test");
     2 
     3 try {
     4     Path newDir = Files.createDirectories(path);
     5 } catch(FileAlreadyExistsException e){
     6     // the directory already exists.
     7 } catch (IOException e) {
     8     //something else went wrong
     9     e.printStackTrace();
    10 }

    2.3、删除文件或目录

      通过 Files.delete()方法 可以删除一个文件或目录:

    1 Path path = Paths.get("data/subdir/logging-moved.properties");
    2 
    3 try {
    4     Files.delete(path);
    5 } catch (IOException e) {
    6     //deleting file failed
    7     e.printStackTrace();
    8 }

    2.4、把一个文件从一个地址复制到另一个位置

      通过Files.copy()方法可以吧一个文件从一个地址复制到另一个位置

     1 Path sourcePath      = Paths.get("data/logging.properties");
     2 Path destinationPath = Paths.get("data/logging-copy.properties");
     3 
     4 try {
     5     Files.copy(sourcePath, destinationPath);
     6 } catch(FileAlreadyExistsException e) {
     7     //destination file already exists
     8 } catch (IOException e) {
     9     //something else went wrong
    10     e.printStackTrace();
    11 }

      copy操作还可可以强制覆盖已经存在的目标文件,只需要将上面的copy()方法改为如下格式:

    1 Files.copy(sourcePath, destinationPath,
    2             StandardCopyOption.REPLACE_EXISTING);

    2.5、获取文件属性

    1 Path path = Paths.get("D:\XMind\bcl-java.txt");
    2 System.out.println(Files.getLastModifiedTime(path));
    3 System.out.println(Files.size(path));
    4 System.out.println(Files.isSymbolicLink(path));
    5 System.out.println(Files.isDirectory(path));
    6 System.out.println(Files.readAttributes(path, "*"));

      结果:

    1 2016-05-18T08:01:44Z
    2 18934
    3 false
    4 false
    5 {lastAccessTime=2017-04-12T01:42:21.149351Z, lastModifiedTime=2016-05-18T08:01:44Z, size=18934, creationTime=2017-04-12T01:42:21.149351Z, isSymbolicLink=false, isRegularFile=true, fil

    2.6、遍历一个文件夹

    1 Path dir = Paths.get("D:\Java");
    2 try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)){
    3     for(Path e : stream){
    4         System.out.println(e.getFileName());
    5     }
    6 }catch(IOException e){
    7 
    8 }

      结果:

    apache-maven-3.5.0
    Eclipse
    intellij idea
    Jar
    JDK
    MarvenRespository
    MyEclipse 2017 CI
    Nodejs
    RedisDesktopManager
    solr-7.2.1

      上面是遍历单个目录,它不会遍历整个目录。遍历整个目录需要使用:Files.walkFileTree().Files.walkFileTree()方法具有递归遍历目录的功能

    2.7、遍历整个文件目录:

      walkFileTree接受一个Path和FileVisitor作为参数。Path对象是需要遍历的目录,FileVistor则会在每次遍历中被调用。

      FileVisitor需要调用方自行实现,然后作为参数传入walkFileTree().FileVisitor的每个方法会在遍历过程中被调用多次。如果不需要处理每个方法,那么可以继承它的默认实现类SimpleFileVisitor,它将所有的接口做了空实现。

     1 public class WorkFileTree {
     2 
     3     public static void main(String[] args) throws IOException{
     4         Path startingDir = Paths.get("D:\apache-tomcat-9.0.0.M17");
     5         List<Path> result = new LinkedList<Path>();
     6         Files.walkFileTree(startingDir, new FindJavaVisitor(result));
     7         System.out.println("result.size()=" + result.size());
     8     }
     9 
    10     private static class FindJavaVisitor extends SimpleFileVisitor<Path>{
    11         private List<Path> result;
    12         public FindJavaVisitor(List<Path> result){
    13             this.result = result;
    14         }
    15         @Override
    16         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs){
    17             if(file.toString().endsWith(".java")){
    18                 result.add(file.getFileName());
    19             }
    20             return FileVisitResult.CONTINUE;
    21         }
    22     }
    23 }

      上面这个例子输出了我的D:apache-tomcat-9.0.0.M17也就是我的Tomcat安装目录下以.java结尾文件的数量。

      结果:

    result.size()=4

      Files类真的很强大,除了我讲的这些操作之外还有其他很多操作比如:读取和设置文件权限、更新文件所有者等等操作。

      这里就介绍这么多了,如果想要详细了解的可以自行查阅官方文档或者相关书籍。

      参考:https://www.cnblogs.com/snailclimb/p/9086333.html

  • 相关阅读:
    Postman的使用和测试
    Django报错 django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
    MySQL 修改字段类型或长度
    mysql导入导出sql文件
    Django 无法同步数据库model相应字段问题
    Django objects.all()、objects.get()与objects.filter()之间的区别介绍
    inconsistent use of tabs and spaces in indentation
    JavaScript 计时器
    JavaScript--编程题
    JavaScript--Array 数组对象
  • 原文地址:https://www.cnblogs.com/h--d/p/14206578.html
Copyright © 2011-2022 走看看