Java 7 中 NIO.2 的使用——第一节 Path 类的使用
路径隶属于文件系统,实际上它是存储和组织媒体文件的格式,通常在一块或多块硬盘设备上,以便于非常容易地检索。文件系统可以通过 java.nio.file.FileSystems 这个final 类来访问,通常我们用来获取它的实例然后做我们想做的事情。FileSystems 包含下面两个非常重要的方法,还有 newFileSystem() 方法,用来构建一个新的文件系统实例。
- getDefault(): 这个静态方法会返回一个默认的FileSystem 给 JVM——通常是操作系统默认的文件系统。
- getFileSystem(URI uri): 这个静态方法根据提供的可以匹配 URI 模式的一系列可用的文件系统提供者中返回一个文件系统。Path类可以操作任何类型的文件系统并可以使用任何存储的地方(java.nio.file.FileStore这个类会呈现潜在的存储)。通常情况下,Path类指向默认的操作系统的文件,但是在 NIO.2 中 彻底模块化了—— 可以是内存中数据,在互联网上,在虚拟文件系统的FileSystem 类的实现,这些都可以都可以完美的被NIO.2接受,NIO.2 提供了所有文件系统的功能,我们需要执行在文件,目录或是一个link 链接文件上。
Path类实际上是java.io.File类的升级版本,但是File类有一些特定的操作,所以File类不要被认为是过时的类,也不要把他当作一个障碍。此外,在Java 7 中,这两个类都是可以继续使用,这就意味着可以混合使用这两个类来获取最佳的 API 操作。 Java 7 中提供了非常简单的API 方便这两者的互相转换。
在以前IO操作都是这样写的。
import java.io.File;
…
File file = new File("index.html");
但在Java7 中,我们可以这样写:
import java.nio.file.Path;
import java.nio.file.Paths;
…
Path path = Paths.get("index.html");
最后总结,一个 Path 类 是一个路径在文件系统中的程序表示。Path基本上就是一个文件路径的字符串,实际的引用的资源可以不存在。
一旦你确定了文件系统和文件或是目录的存储的地方,你就可以创建一个Path实例。绝对路径,相对路径,使用“.”定义的当前路径以及“..” 定义的父级路径,路径中包含一个文件或是目录名字,这些都可以用Path类来搞定。最简单办法是使用Paths帮助类来调用get() 方法。下面的例子演示了使用同一路径定义path的几种不同的方法。默认使用C:\rafaelnadal\tournaments\2009\BNP.txt这个路径。
定义一个绝对目录
一个绝对目录就是包含了根目录然后接下来几层子目录最后是文件名或是最后一层的目录。你可以使用下面代码来定义一个绝对目录Path类。
Path path = Paths.get("C:/rafaelnadal/tournaments/2009/BNP.txt");
get()方法也支持把路径分割成一块一块的。NIO会重新组织路径。看下面代码:
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");
定义一个相对于根路径的相对路径
相对路径是全路径的一部分,相对路径通常用在创建web 页面中。相对路径要比绝对路径用的更加广泛。在当前路径下保存一个相对路径通常要加上文件分隔符。例如,如果当前路径是C盘,则绝对路径应该是:C:\rafaelnadal\tournaments\2009\BNP.txt
:
Path path = Paths.get("/rafaelnadal/tournaments/2009/BNP.txt");
Path path = Paths.get("/rafaelnadal","tournaments/2009/BNP.txt");
定义一个相对于工作目录的相对路径
当你定义一个相对于当前工作目录的路径,这个路径就不用使用文件分隔符作为开始。例如向前目录是相对于根目录C盘下的/ATP目录,则根据下面的代码返回绝对路径是:C:\ATP\rafaelnadal\tournaments\2009\BNP.txt
:
Path path = Paths.get("rafaelnadal/tournaments/2009/BNP.txt");
Path path = Paths.get("rafaelnadal","tournaments/2009/BNP.txt");
定义一个从URI获取的路径
在一些情况下,你需要从URI中创建一个路径,你可以使用URI.create() 方法根据指定的字符串从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() 方法来定义一个Path类。
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();
获取系统的主目录的路径
当你想获取主目录的路径时,可以使用下面的代码:
Path path = Paths.get(System.getProperty("user.home"), "downloads", "game.exe");
在Windows 7 中,返回的路径是C:\Users\{your user name}\downloads\game.exe,在Linux系统中,则返回
/home/{your user name}/downloads/game.exe。
----------------------------------------------------------------------------------------------------------------------------
获取路径的信息
当你定义完Path对象后,接下来会有一系列的方法用来访问文件的信息。首先定义一个Path实例:
Path path = Paths.get("C:", "rafaelnadal/tournaments/2009", "BNP.txt");
获取文件或目录的名字:
//output: BNP.txt
System.out.println("The file/directory indicated by path: " + path.getFileName());
获取根目录
//output: C:\
System.out.println("Root of this path: " + path.getRoot());
获取路径的父目录
//output: C:\rafaelnadal\tournaments\2009
System.out.println("Parent: " + path.getParent());
获取路径名的元素
你可以使用 getNameCount()方法获取路径层级的个数,然后再使用getName()循环遍历每个元素的名字。
//output: 4
System.out.println("Number of name elements in path: " + path.getNameCount()); //output: rafaelnadal tournaments 2009 BNP.txt
for (int i = 0; i < path.getNameCount(); i++) {
System.out.println("Name element " + i + " is: " + path.getName(i));
}
获取子路径
//output: rafaelnadal\tournaments\2009
System.out.println("Subpath (0,3): " + path.subpath(0, 3));
--------------------------------------------------------------------------------------------------------------------------
Path的转换
在这节中,将会介绍怎样由一个Path对象转换成字符串,URI,绝对路径,相对路径以及File对象。
先定义一个Path实例:
Path path = Paths.get("/rafaelnadal/tournaments/2009", "BNP.txt");
转化成一个字符串
//output: \rafaelnadal\tournaments\2009\BNP.txt
String path_to_string = path.toString();
System.out.println("Path to String: " + path_to_string);
转换成一个URI
//output: file:///C:/rafaelnadal/tournaments/2009/BNP.txt
URI path_to_uri = path.toUri();
System.out.println("Path to URI: " + path_to_uri);
由相对路径转换成绝对路径
//output: C:\rafaelnadal\tournaments\2009\BNP.txt
Path path_to_absolute_path = path.toAbsolutePath();
System.out.println("Path to absolute path: " + path_to_absolute_path.toString());
转换成真实路径
import java.io.IOException;
…
//output: C:\rafaelnadal\tournaments\2009\BNP.txt
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);
}
转换成File对象
//output: BNP.txt
File path_to_file = path.toFile(); //output: \rafaelnadal\tournaments\2009\BNP.txt
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());
--------------------------------------------------------------------------------------------------------------------------
合并两个路径
合并两个路径的技术允许你先定义一个固定的根目录然后再附上局部的路径,在NIO.2 中,使用resolve() 方法来实现这一功能。
//define the fixed path
Path base = Paths.get("C:/rafaelnadal/tournaments/2009"); //resolve BNP.txt file
Path path_1 = base.resolve("BNP.txt");
//output: C:\rafaelnadal\tournaments\2009\BNP.txt
System.out.println(path_1.toString()); //resolve AEGON.txt file
Path path_2 = base.resolve("AEGON.txt");
//output: C:\rafaelnadal\tournaments\2009\AEGON.txt
System.out.println(path_2.toString());
还有一个方法用于兄弟路径,叫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");
//output: C:\rafaelnadal\tournaments\2009\AEGON.txt
System.out.println(path.toString());
--------------------------------------------------------------------------------------------------------------------------------
在两个位置中构造一个路径
当你需要构造从一个位置到另一个位置的路径的时候,你可以使用relativize()方法。直接上代码。
Path path01 = Paths.get("BNP.txt");
Path path02 = Paths.get("AEGON.txt");
在这种情况下,可以假设这两个txt文件在同一层目录下,这就意味着你你可以从一个文件导航到另一个文件根据目录的层级。
//output: ..\AEGON.txt
Path path01_to_path02 = path01.relativize(path02);
System.out.println(path01_to_path02); //output: ..\BNP.txt
Path path02_to_path01 = path02.relativize(path01);
System.out.println(path02_to_path01);
另一种情况是两个文件不在同一层的目录中,考虑下面的这个情况:
Path path01 = Paths.get("/tournaments/2009/BNP.txt");
Path path02 = Paths.get("/tournaments/2011");
这两个路径都有一个共同的根元素:/tournaments, 从path01 导航到 path02,你需要向上两个目录层级然后再向下一个层级(
..\..\2011
)。从path02导航到path01,你需要向上一个层级然后向下两个层级,relativize()方法就是这样做的。
//output: ..\..\2011
Path path01_to_path02 = path01.relativize(path02);
System.out.println(path01_to_path02); //output: ..\2009\BNP.txt
Path path02_to_path01 = path02.relativize(path01);
System.out.println(path02_to_path01);
注意,如果只有一个path包含根元素,那么相对路径是不能构造的,必保证两个path包含根元素。即使这样,相对路径的构造是依赖于系统的。
-----------------------------------------------------------------------------------------------------------------------------------
比较两个路径
两个路径是否相等可以通过不同的方式和目的去测试。你可以使用 Path.equals()方法,这个方法并不直接访问文件系统,所以没有强制要求文件必须存在,
也不会检查两个文件是否是同一个文件。在有的系统中,路径的比较会忽略大小写,有的则是大小写敏感的。下面的代码中表示的是同一个文件,但是并不相等。
Path path01 = Paths.get("/rafaelnadal/tournaments/2009/BNP.txt");
Path path02 = Paths.get("C:/rafaelnadal/tournaments/2009/BNP.txt"); if(path01.equals(path02)){
System.out.println("The paths are equal!");
} else {
System.out.println("The paths are not equal!"); //true
}
有时候你想检查两个路径是否是同一个目录和文件,你可以很容易地使用java.nio.File.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()方法对路径进行比较,根据字典顺序进行比较。
//output: 24
int compare = path01.compareTo(path02);
System.out.println(compare);
还可以进行局部路径的比较。
boolean sw = path01.startsWith("/rafaelnadal/tournaments");
boolean ew = path01.endsWith("BNP.txt");
System.out.println(sw); //output: true
System.out.println(ew); //output: true
------------------------------------------------------------------------------------------------------------------------------
遍历路径元素的名称
因为Path实现了Iterable接口,所以你可以得到一个对象然后新型循环遍历一个路径的信息。请看下面的代码。
Path path = Paths.get("C:", "rafaelnadal/tournaments/2009", "BNP.txt"); for (Path name : path) {
System.out.println(name);
}
输出结构如下所示:
rafaelnadal
tournaments
2009
BNP.txt
-----------------------------------------------------------------------------------------------------------------------------
完。
Java 7 中 NIO.2 的使用——第一节 Path 类的使用的更多相关文章
- Java 7 中 NIO.2 的使用——第二节 元数据文件的属性
如果你有很多疑问关于一个文件或目录,它是否是隐藏的,它的大小是多少,谁拥有它,你可以从元数据中得到这些信息.所谓的元数据,就是描述数据的数据. NIO.2组织了这些原数据的属性的概念,并提供了java ...
- Java 7 中 NIO.2 的使用——文件递归操作
众所周知,递归编程是一项有争议的技术,因为它需要大量的内存,但是它能简化一些编程任务.基本上,一个递归操作都是程序调用自己传递参数修改的值或者参数传递到当前的程序循环中.递归编程通常用来计算阶乘斐波那 ...
- Java 7 中 NIO.2 的使用——第四节 文件和目录
Files类提供了很多方法用于检查在于你真正实际去操作一个文件或目录.这些方法强烈推荐,也非常有用,也能避免很多异常的发生.例如,一个很好的习惯就是在你试着移动一个文件从一个地方到另一个地方的时候,先 ...
- Java文件中为什么只能有一个public修饰的类, 并且类名还必须与文件名相同
当编写一个java源代码文件时,此文件通常被称为编译单元(有时也被称为转译单元).每个编译单元都必须有一个后缀名.java,而在编译单元内则可以有一个public类,该类的名称必须与文件的名称相同(包 ...
- 对Java配置文件中敏感信息进行加解密的工具类
在 JavaEE 配置文件中,例如 XML 或者 properties 文件,由于某些敏感信息不希望普通人员看见,则可以采用加密的方式存储,程序读取后进行解密. 常见的如: 数据库用户密码,短信平台用 ...
- java程序中访问https时,报 PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
在java中使用https访问数据时报异常: Caused by: sun.security.validator.ValidatorException: PKIX path building fail ...
- 《MonkeyRunner原理剖析》第九章-MonkeyImage实现原理 - 第一节 - 关键类作用及关系
MonkeyRunner框架暴露了几个类的大量的API出去给用户编写脚本时候使用,其中最主要的三个就是: MonkeyDevice目标设备操作类,HierarchyViewer窗口界面对象操作类以及M ...
- 在 Java 8 中获取日期
前言 前面一篇文章写了<SimpleDateFormat 如何安全的使用?>, 里面介绍了 SimpleDateFormat 如何处理日期/时间,以及如何保证线程安全,及其介绍了在 Jav ...
- 20 个案例教你在 Java 8 中如何处理日期和时间?
前言 前面一篇文章写了<SimpleDateFormat 如何安全的使用?>, 里面介绍了 SimpleDateFormat 如何处理日期/时间,以及如何保证线程安全,及其介绍了在 Jav ...
随机推荐
- NodeJs 中的Crypto 加密模块
加密技术通常分为两大类:“对称式”和“非对称式”. 对称式加密: 就是加密和解密使用同一个密钥,通常称之为“Session Key ”这种加密技术在当今被广泛采用,如美国政府所采用的DES加密标准就是 ...
- POJ C++程序设计 编程作业—类和对象 编程题#3
编程题 #3 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 下面程序的输出 ...
- Linux使用Shell脚本实现ftp的自动上传下载
1. ftp自动登录批量下载文件. #####从ftp服务器上的/home/data 到 本地的/home/databackup#####!/bin/bashftp -n<<!open 1 ...
- 用户 'sa' 登录失败。 (Microsoft SQL Server,错误: 18456)
今天登陆数据库的时候,却忽然登陆了不了,并且提示了这样的错: 解决方法: 1.用Windows身份登录数据库 2.安全性==>登录名==>双击sa 3.重设密码 4.状态==>登录: ...
- freefilesync 7 使用
官方下载地址:http://www.freefilesync.org/download.php 1.打开FreeFileSync 设置左右的文件夹,设置过滤规则,设置同步方式(双向.单向),执行同步 ...
- 利用js的for循环实现一个简单的“九九乘法表”
For循环九九乘法表 for循环是javascript中一种常用的循环语句,可以很好的解决在程序中需要重复执行某些语句,利用for循环实现简单的“九九乘法表”的效果: 让循环从小到大,依次排序,并计算 ...
- Zookeeper 脑裂
转自 http://blog.csdn.net/u010185262/article/details/49910301 Zookeeper zookeeper是一个分布式应用程序的协调服务.它是一个为 ...
- MYSQL数据库表中字段追加字符串内容
$sql="update parts set p_notes=concat(p_notes,'{$p_notes}') where p_id={$p_id}"; parts为表名 ...
- 使用supervisor的一些注意事项
一直都有在使用supervisor来管理linux上的服务进程.最近有同事说有某服务貌似有问题,让上去检查一下.上去以后发现某服务反应的确很慢,所以就用supervisor重启一下.但是重启的时候就发 ...
- 刀哥多线程Barrier异步gcd-08-barrier_async
Barrier 异步 主要用于在多个异步操作完成之后,统一对非线程安全的对象进行更新 适合于大规模的 I/O 操作 代码演练 准备工作 @interface ViewController () { / ...