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学习资源):
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
燃!Java全球标准中国人参与制定,阿里成首个受邀中国公司
2018年5月17日,作为唯一中国代表,阿里巴巴获邀加入Java全球管理组织Java Community Process (JCP)的最高执行委员会。此次获得执行委员会席位,让中国企业首次加入到Java全球标准的制定中,更多“中国标准”有望成为全球规范。 JCP是一个开放性的国际技术标准组织,职责是发展和更新Java技术规范。由24个成员组成的执行委员会则是该组织的最高决策机构,负责规划Java的技术演进方向。 图:阿里巴巴加入 Java管理组织Java Community Process (JCP)执行委员会 Java是全球使用最为广泛的开发语言之一。目前Java技术已无处不在,无论是手机应用、电脑软件还是物联网,众多中国互联网企业也将Java作为主要编程语言。但长期以来,Java标准规范的制定主要由甲骨文、ARM、IBM、Intel
- 下一篇
Nginx upload上传模块(学习笔记十七)
上传模块配置样例: # 上传大小限制(包括所有内容) client_max_body_size 100m; # 上传path配置 location /upload { # 转到后台处理URL upload_pass /uploadHandle; # 临时保存路径 # 可以使用散列 upload_store /tmp/nginx_upload; # 上传文件的权限,rw表示读写 r只读 upload_store_access user:rw; # 这里写入http报头,pass到后台页面后能获取这里set的报头字段 upload_set_form_field "${upload_field_name}_name"$upload_file_name; upload_set_form_field "${upload_field_name}_content_type"$upload_content_type; upload_set_form_field "${upload_field_name}_path"$upload_tmp_path; # Upload模块自动生成的一些信息,如文件大小与...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Hadoop3单机部署,实现最简伪集群
- CentOS8编译安装MySQL8.0.19
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Mario游戏-低调大师作品
- CentOS6,CentOS7官方镜像安装Oracle11G