01-java nio之Path使用

JDK7引入了NIO.2 API,它是JSR203:More New I/O APIs for the Java Platform的实现,主要涉及抽象类java.nio.file.Path.Path类支持两种类型的操作:句法操作(syntactic operations,大多数涉及到path的都不用访问文件系统,只是内存中的逻辑操作)和有关path的文件操作。

1.1 Path类介绍

文件系统可以通过java.nio.file.FileSystems静态类(用来获取java.nio.file.FileSystem实例),FileSystems类包括3个newFileSystem方法、用于获取当前JVM默认的文件系统的getDefault()静态方法和 通过URI获取文件系统的getFileSystem(URI uri)静态方法。 Path类是java.io.File的升级版本。对比下两者之间操作上的差异:

import java.io.File;
…
File file = new File("index.html");
NIO.2版本 
import java.nio.file.Path;
import java.nio.file.Paths;
…
Path path = Paths.get("index.html");

1.2 定义一个Path

Paths类只包含两个方法:

public static Path get(String first, String ... more) {
    return FileSystems .getDefault().getPath (first , more) ;
}

public static Path get(URI uri) {
    String scheme =  uri. getScheme() ;
    if (scheme == null)
        throw new IllegalArgumentException ("Missing scheme");

    // check for default provider to avoid loading of installed providers
    if (scheme .equalsIgnoreCase ("file" ))
        return FileSystems.getDefault (). provider() .getPath (uri );

    // try to find provider
    for (FileSystemProvider provider : FileSystemProvider.installedProviders ()) {
        if (provider .getScheme (). equalsIgnoreCase(scheme )) {
            return provider. getPath( uri) ;
        }
    }

    throw new FileSystemNotFoundException ("Provider \"" + scheme + "\" not installed" );
}

具体使用如下:

//定义一个绝对路径Path
Path path = Paths.get("C:/rafaelnadal/tournaments/2009/BNP.txt");
Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
Path path = Paths.get("C:", "rafaelnadal/tournaments/2009", "BNP.txt");
Path path = Paths.get("C:", "rafaelnadal", "tournaments", "2009", "BNP.txt");

//定义一个当前工作目录的相对路径的Path
Path path = Paths.get("rafaelnadal/tournaments/2009/BNP.txt");
Path path = Paths.get("rafaelnadal","tournaments/2009/BNP.txt");

//使用短路径定义path
Path noNormalize = Paths.get("C:/rafaelnadal/tournaments/./2009/dummy/../BNP.txt");
Path normalize = Paths.get("C:/rafaelnadal/tournaments/./2009/dummy/../BNP.txt").normalize();
//注意:normalize的区别在于是否会解析.和..。
C:\rafaelnadal\tournaments\.\2009\dummy\..\BNP.txt
C:\rafaelnadal\tournaments\2009\BNP.txt

//定义一个uri路径
import java.net.URI;
Path path = Paths.get(URI.create("file:///rafaelnadal/tournaments/2009/BNP.txt"));
Path path = Paths.get(URI.create("file:///C:/rafaelnadal/tournaments/2009/BNP.txt"));

//使用FileSystems.getDefault().getPath()方法定义一个路径
import java.nio.file.FileSystems;
Path path = FileSystems.getDefault().getPath("/rafaelnadal/tournaments/2009", "BNP.txt");
Path path = FileSystems.getDefault().getPath("/rafaelnadal/tournaments/2009/BNP.txt");
Path path = FileSystems.getDefault().getPath("rafaelnadal/tournaments/2009", "BNP.txt");
Path path = FileSystems.getDefault().getPath("/rafaelnadal/tournaments/./2009","BNP.txt").normalize();

//从home目录获取路径
Path path = Paths.get(System.getProperty("user.home"), "downloads", "game.exe");

1.3 获取Path属性

Path path = Paths.get("C:/rafaelnadal/tournaments/./2009/dummy/../BNP.txt") ;
//获取文件或目录名
System.out.println("The file/directory indicated by path: " + path.getFileName());
//output: BNP.txt

//获取Path Root
System.out.println("Root of this path: " + path.getRoot());
//output: C:\

//获取Path 父目录
System.out.println("Parent: " + path.getParent());
//output: C:\rafaelnadal\tournaments\2009

//获取Path名字元素
System.out.println("Number of name elements in path: " + path.getNameCount());
//output: 4 
for (int i = 0; i < path.getNameCount(); i++) {
    System.out.println("Name element " + i + " is: " + path.getName(i));
}
//output: rafaelnadal  tournaments   2009   BNP.txt

//获取路径的子路径
System.out.println("Subpath (0,3): " + path.subpath(0, 3));
//output: rafaelnadal\tournaments\2009

1.4 转换Path

Path path = Paths.get("/rafaelnadal/tournaments/2009", "BNP.txt");
//Path转换为字符串
System.out.println("Path to String: " + path.toString());
Path to String: \rafaelnadal\tournaments\2009\BNP.txt


//Path转换为URI,可以在web页面浏览的路径。
System.out.println("Root of this path: " + path.toUri());
Root of this path: file:///D:/rafaelnadal/tournaments/2009/BNP.txt

//Path转换绝对路径
 System.out.println("Path to absolute path: " + path.toAbsolutePath().toString());
Path to absolute path: D:\rafaelnadal\tournaments\2009\BNP.txt

//Path转换为实际的路径
如果Path不存在或无访问权限,会报异常。
try {
     Path real_path = path.toRealPath(LinkOption.NOFOLLOW_LINKS);  // 忽略符号链接
     System.out.println("Path to real path: " + real_path);
} catch (NoSuchFileException e) {
     System.err.println(e);
} catch (IOException e) {
     System.err.println(e);
}
java.nio.file.NoSuchFileException 

//Path转换为File
File path_to_file = path.toFile();
Path file_to_path = path_to_file.toPath();
System.out.println("Path to file name: " + path_to_file.getName());
System.out.println("File to path: " + file_to_path.toString());
//output: Path to file name: BNP.txt
//output: File to path: \rafaelnadal\tournaments\2009\BNP.txt

1.5 拼接Path

//define the fixed path
Path base = Paths.get("C:/rafaelnadal/tournaments/2009");

//resolve BNP.txt file
Path path_1 = base.resolve("BNP.txt");
System.out.println(path_1.toString());
//output: C:\rafaelnadal\tournaments\2009\BNP.txt 

resolveSibling相当于分离出父目录,下面的例子用户替换文件名。 
//define the fixed path
Path base = Paths.get("C:/rafaelnadal/tournaments/2009/BNP.txt");
//resolve sibling AEGON.txt file
Path path = base.resolveSibling("AEGON.txt");
System.out.println(path.toString());
//output: C:\rafaelnadal\tournaments\2009\AEGON.txt

1.6在两个位置间转换Path

两个位置必须都包含root元素。即必须能够通过.或者..互相访问。
Path path01 = Paths.get("/tournaments/2009/BNP.txt");
Path path02 = Paths.get("/tournaments/2011");

Path path01_to_path02 = path01.relativize(path02);
System.out.println(path01_to_path02);
//output: ..\..\2011

Path path02_to_path01 = path02.relativize(path01);
System.out.println(path02_to_path01);
//output: ..\2009\BNP.txt

1.7 比较两个Path

Path path01 = Paths.get("/rafaelnadal/tournaments/2009/BNP.txt");
Path path02 = Paths.get("C:/rafaelnadal/tournaments/2009/BNP.txt");
if(path01.equals(path02)){  // 不会检查文件是否存在,有些平台区分大小写,和Object.equals()类似。
     System.out.println("The paths are equal!");
} else {
     System.out.println("The paths are not equal!"); //true
}

在equals返回false之后,调用 Files.isSameFile检查。

try {
     boolean check = Files.isSameFile(path01, path02);
     if(check){
          System.out.println("The paths locate the same file!"); //true
     } else {
          System.out.println("The paths does not locate the same file!");
     }
} catch (IOException e) {
     System.out.println(e.getMessage());
}

由于Path类实现了Comparable接口,所以可以使用compareTo方法比较两个Path。

int compare = path01.compareTo(path02);
System.out.println(compare);  //output: 24

boolean sw = path01.startsWith("/rafaelnadal/tournaments");
boolean ew = path01.endsWith("BNP.txt");
System.out.println(sw); //output: true
System.out.println(ew); //output: true

1.8迭代Path中的Name元素

由于实现了Iterator接口,所以可以使用显式的Iterator或者如下的foreach方法迭代获取Path中的Name。

Path path = Paths.get("C:", "rafaelnadal/tournaments/2009", "BNP.txt");
for (Path name : path) {
     System.out.println(name);
}
输出:
rafaelnadal
tournaments
2009
BNP.txt

猜你喜欢

转载自my.oschina.net/funcy/blog/1820868
今日推荐