Java NIO之拥抱Path和Files
Java面试通关手册(Java学习指南)github地址(欢迎star和pull):https://github.com/Snailclimb/Java_Guide
历史回顾:
其他高赞文章:
一 文件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 创建一个Path
创建Path实例可以通过 Paths工具类 的 get()方法:
//使用绝对路径
Path path= Paths.get("c:\\data\\myfile.txt");
//使用相对路径
Path path = Paths.get("/home/jakobjenkov/myfile.txt");
下面这种创建方式和上面等效:
Path path = FileSystems.getDefault().getPath("c:\\data\\myfile.txt");
2 File和Path之间的转换,File和URI之间的转换
File file = new File("C:/my.ini");
Path p1 = file.toPath();
p1.toFile();
file.toURI();
3 获取Path的相关信息
//使用Paths工具类的get()方法创建
Path path = Paths.get("D:\\XMind\\bcl-java.txt");
/* //使用FileSystems工具类创建
Path path2 = FileSystems.getDefault().getPath("c:\\data\\myfile.txt");*/
System.out.println("文件名:" + path.getFileName());
System.out.println("名称元素的数量:" + path.getNameCount());
System.out.println("父路径:" + path.getParent());
System.out.println("根路径:" + path.getRoot());
System.out.println("是否是绝对路径:" + path.isAbsolute());
//startsWith()方法的参数既可以是字符串也可以是Path对象
System.out.println("是否是以为给定的路径D:开始:" + path.startsWith("D:\\") );
System.out.println("该路径的字符串形式:" + path.toString());
结果:
文件名:bcl-java.txt
名称元素的数量:2
父路径:D:\XMind
根路径:D:\
是否是绝对路径:true
是否是以为给定的路径D:开始:true
该路径的字符串形式:D:\XMind\bcl-java.txt
4 移除冗余项
某些时候在我们需要处理的Path路径中可能会有一个或两个点
- .表示的是当前目录
- ..表示父目录或者说是上一级目录:
下面通过实例来演示一下使用Path类的normalize()和toRealPath()方法把.和..去除。
- normalize() : 返回一个路径,该路径是冗余名称元素的消除。
- toRealPath() : 融合了toAbsolutePath()方法和normalize()方法
//.表示的是当前目录
Path currentDir = Paths.get(".");
System.out.println(currentDir.toAbsolutePath());//输出C:\Users\Administrator\NIODemo\.
Path currentDir2 = Paths.get(".\\NIODemo.iml");
System.out.println("原始路径格式:"+currentDir2.toAbsolutePath());
System.out.println("执行normalize()方法之后:"+currentDir2.toAbsolutePath().normalize());
System.out.println("执行toRealPath()方法之后:"+currentDir2.toRealPath());
//..表示父目录或者说是上一级目录:
Path currentDir3 = Paths.get("..");
System.out.println("原始路径格式:"+currentDir3.toAbsolutePath());
System.out.println("执行normalize()方法之后:"+currentDir3.toAbsolutePath().normalize());
System.out.println("执行toRealPath()方法之后:"+currentDir3.toRealPath());
结果:
C:\Users\Administrator\NIODemo\.
原始路径格式:C:\Users\Administrator\NIODemo\.\NIODemo.iml
执行normalize()方法之后:C:\Users\Administrator\NIODemo\NIODemo.iml
执行toRealPath()方法之后:C:\Users\Administrator\NIODemo\NIODemo.iml
原始路径格式:C:\Users\Administrator\NIODemo\..
执行normalize()方法之后:C:\Users\Administrator
执行toRealPath()方法之后:C:\Users\Administrator
二 拥抱Files类
Java NIO中的Files类(java.nio.file.Files)提供了多种操作文件系统中文件的方法。本节教程将覆盖大部分方法。Files类包含了很多方法,所以如果本文没有提到的你也可以直接查询JavaDoc文档。
java.nio.file.Files类是和java.nio.file.Path相结合使用的
1 检查给定的Path在文件系统中是否存在
通过 Files.exists() 检测文件路径是否存在:
Path path = Paths.get("D:\\XMind\\bcl-java.txt");
boolean pathExists =
Files.exists(path,
new LinkOption[]{LinkOption.NOFOLLOW_LINKS});
System.out.println(pathExists);//true
注意Files.exists()的的第二个参数。它是一个数组,这个参数直接影响到Files.exists()如何确定一个路径是否存在。在本例中,这个数组内包含了LinkOptions.NOFOLLOW_LINKS,表示检测时不包含符号链接文件。
2 创建文件/文件夹
- 创建文件:
通过 Files.createFile() 创建文件,
Path target2 = Paths.get("C:\\mystuff.txt");
try {
if(!Files.exists(target2))
Files.createFile(target2);
} catch (IOException e) {
e.printStackTrace();
}
创建文件夹:
- 通过 Files.createDirectory() 创建文件夹
- 通过 Files.createDirectories() 创建文件夹
Files.createDirectories()会首先创建所有不存在的父目录来创建目录,而Files.createDirectory()方法只是创建目录,如果它的上级目录不存在就会报错。比如下面的程序使用Files.createDirectory() 方法创建就会报错,这是因为我的D盘下没有data文件夹,加入存在data文件夹的话则没问题。
Path path = Paths.get("D://data//test"); try {
Path newDir = Files.createDirectories(path);
} catch(FileAlreadyExistsException e){
// the directory already exists.
} catch (IOException e) {
//something else went wrong
e.printStackTrace();
}
3 删除文件或目录
通过 Files.delete()方法 可以删除一个文件或目录:
Path path = Paths.get("data/subdir/logging-moved.properties");
try {
Files.delete(path);
} catch (IOException e) {
//deleting file failed
e.printStackTrace();
}
4 把一个文件从一个地址复制到另一个位置
通过Files.copy()方法可以吧一个文件从一个地址复制到另一个位置
Path sourcePath = Paths.get("data/logging.properties");
Path destinationPath = Paths.get("data/logging-copy.properties");
try {
Files.copy(sourcePath, destinationPath);
} catch(FileAlreadyExistsException e) {
//destination file already exists
} catch (IOException e) {
//something else went wrong
e.printStackTrace();
}
copy操作还可可以强制覆盖已经存在的目标文件,只需要将上面的copy()方法改为如下格式:
Files.copy(sourcePath, destinationPath,
StandardCopyOption.REPLACE_EXISTING);
5 获取文件属性
Path path = Paths.get("D:\\XMind\\bcl-java.txt");
System.out.println(Files.getLastModifiedTime(path));
System.out.println(Files.size(path));
System.out.println(Files.isSymbolicLink(path));
System.out.println(Files.isDirectory(path));
System.out.println(Files.readAttributes(path, "*"));
结果:
2016-05-18T08:01:44Z
18934
false
false
{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
6 遍历一个文件夹
Path dir = Paths.get("D:\\Java");
try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)){
for(Path e : stream){
System.out.println(e.getFileName());
}
}catch(IOException e){
}
结果:
apache-maven-3.5.0
Eclipse
intellij idea
Jar
JDK
MarvenRespository
MyEclipse 2017 CI
Nodejs
RedisDesktopManager
solr-7.2.1
上面是遍历单个目录,它不会遍历整个目录。遍历整个目录需要使用:Files.walkFileTree().Files.walkFileTree()方法具有递归遍历目录的功能。
7 遍历整个文件目录:
walkFileTree接受一个Path和FileVisitor作为参数。Path对象是需要遍历的目录,FileVistor则会在每次遍历中被调用。
FileVisitor需要调用方自行实现,然后作为参数传入walkFileTree().FileVisitor的每个方法会在遍历过程中被调用多次。如果不需要处理每个方法,那么可以继承它的默认实现类SimpleFileVisitor,它将所有的接口做了空实现。
public class WorkFileTree {
public static void main(String[] args) throws IOException{
Path startingDir = Paths.get("D:\\apache-tomcat-9.0.0.M17");
List<Path> result = new LinkedList<Path>();
Files.walkFileTree(startingDir, new FindJavaVisitor(result));
System.out.println("result.size()=" + result.size());
}
private static class FindJavaVisitor extends SimpleFileVisitor<Path>{
private List<Path> result;
public FindJavaVisitor(List<Path> result){
this.result = result;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs){
if(file.toString().endsWith(".java")){
result.add(file.getFileName());
}
return FileVisitResult.CONTINUE;
}
}
}
上面这个例子输出了我的D:\apache-tomcat-9.0.0.M17也就是我的Tomcat安装目录下以.java结尾文件的数量。
结果:
result.size()=4
Files类真的很强大,除了我讲的这些操作之外还有其他很多操作比如:读取和设置文件权限、更新文件所有者等等操作。
我这里就介绍这么多了,如果想要详细了解的可以自行查阅官方文档或者相关书籍。
欢迎关注我的微信公众号:”Java面试通关手册”(一个有温度的微信公众号,期待与你共同进步~~~坚持原创,分享美文,分享各种Java学习资源):
Java NIO之拥抱Path和Files的更多相关文章
- NIO前奏之Path、Files、AsynchronousFileChannel
NIO前奏之Path.Files.AsynchronousFileChannel Java 1.4加入了nio包,Java 1.7 加入了真正的AIO(异步IO),AsynchronousFile ...
- NIO.2中Path,Paths,Files类的使用
Java NIO Java NIO概述 Java NIO(New IO(新io),Non-Blocking IO(非阻塞的io))是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的 ...
- JAVA nio 2 定义 Path 类
一旦确认了文件系统上的一个文件或目录,那么就可以定义一个 Path 类来指向它.定义 Path 类可以使用绝对路径.相对路径.路径中带有一个点号“.”(表示当前目录).路径中带有两个点“..”(表示上 ...
- JAVA nio 2 和 Path 类简介
想要初步了解 NIO.2 API,也就是通常所说的“JSR203: More New I/O APIs for the Java Platform”,最好的切入点就是新的抽象类 java.nio.fi ...
- Java文件IO操作应该抛弃File拥抱Path和Files
Java7中文件IO发生了很大的变化,专门引入了很多新的类: import java.nio.file.DirectoryStream;import java.nio.file.FileSystem; ...
- Java NIO学习(Path接口、Paths和Files工具类的使用)
NIO学习:Paths和Files工具类的使用 JDK1.7引入了新的IO操作类.在java.nio.file包下,Java NIO Path接口和Files类. Path接口:Path表示的是一个目 ...
- Java NIO.2 使用Path接口来监听文件、文件夹变化
Java7对NIO进行了大的改进,新增了许多功能: 对文件系统的访问提供了全面的支持 提供了基于异步Channel的IO 这些新增的IO功能简称为 NIO.2,依然在java.nio包下. 早期的Ja ...
- Java NIO文章列表(强烈推荐 转)
IO流学习总结 一 Java IO,硬骨头也能变软 二 java IO体系的学习总结 三 Java IO面试题 NIO与AIO学习总结 一 Java NIO 概览 二 Java NIO 之 Buffe ...
- Java NIO Related
A file's status is 3-valued: The file is verified to exist; The file is verified to not exist; The f ...
随机推荐
- 用ClientDataSet更新数据表,怎样自动生成行号? [问题点数:40分]
ClientDataSet.First;while not ClientDataSet.eof dobegin ClientDataSet.edit; ClientDataSet.FieldByN ...
- PHP中测试in_array、isset、array_key_exists性能
测试in_array.isset.array_key_exists性能.自己写的简易测试代码: ini_set('display_errors',true); error_reporting(E_AL ...
- 第215天:Angular---指令
指令(Directive) AngularJS 有一套完整的.可扩展的.用来帮助 Web 应用开发的指令集 在 DOM 编译期间,和 HTML 关联着的指令会被检测到,并且被执行 在 AngularJ ...
- linq 左连接实现两个集合的合并
//第一个集合为所有的数据 var specilist = new List<Me.SpecificationsInfo>(); var resultall = (from a in db ...
- servletActionContext.getContext默认获取contextmap 数据默认存储在contextmap的request中
- 子类使用父类的方法 或属性时候 里面的this 代表的是自己
- ADO.NET:C#/SQL Server
1.首次要准备的(工具)是:a.Microsoft Visual Studio Ultimate 2012;b.Microsoft SQL Server Management Studio ; 2.首 ...
- 最新wireshark抓包教程
http://jingyan.baidu.com/article/d71306350f213b13fdf475b9.html 大家都知道,sniffer是一款收费产品, 要真正的学会使用,因为有许多的 ...
- Android Studio中多项目共享Library
FAQ: as的projectA中有一个commonLib的源码库模块,projectB要调用其中的commonLib, 这个有没有方案?不用手动拷贝aar的 方案1. 采用gradle配置参数方 ...
- Centos6.6下安装nginx1.6.3
安装环境: [root@nginx ~]# cat /etc/redhat-release CentOS release 6.6 (Final) [root@nginx ~]# uname -r 2. ...