Path和Files类封装了在用户机器上处理文件系统所需的所有功能。例如,Files类可以用来移除或重命名文件,或者查询文件最后被修改的时间。换句话说,输入/输出流类关心的是文件的内容,而Path和Files类关心的是在磁盘上如何储存文件。
一.Path
Path
表示的是一个目录名序列,其后还可以跟着一个文件名。路径中的第一个部件可以是根部件,例如 / 或 C:\ ,而允许访问的根部件取决于文件系统。以根部件开始的路径是绝对路径;否则,就是相对路径。例如,我们要分别创建一个绝对路径和一个相对路径;其中,对于绝对路径,假设计算机运行的是类Unix的文件系统:
//Unix系统
Path absolute = Paths.get("/home", "harry");
Path relative = Paths.get("myprog", "conf", "user.properties");
- 静态的
Paths.get
方法接受一个或多个字符串,并将它们用默认文件系统的路径分割符(类Unix文件系统是 / ,Windows是 \ )连接起来。然后它解析连接起来的结果,如果其表示的不是给定文件系统中的合法路径,那么就抛出InvalidPathException
异常。这个连接起来的结果就是一个Path
对象。 - get方法可以获取包含多个部件构成的单个字符串,例如,可以像下面这样从配置文件中读出路径
Properties props = new Properties();
String baseDir = props.getProperty("base.dir");
// Path basePath = Paths.get(baseDir);
System.out.println(baseDir);
- 组合或解析路径是司空见惯的操作,调用p.resolve(q)将按照如下规则返回一个路径
如果q是绝对路径,则结果就是q
否则,根据文件系统的规则,将"p后面跟着q"作为结果
- 例如,假设你的应用系统需要查找相对于给定基目录的工作目录,其中基目录是从配置文件中读取的。
Path workRelative = Paths.get("work");
Path workPath = basePath.resolve(workRelative);
- resolve方法有一种快捷方式,它接受一个字符串而不是路径。
- 还有一个很方便的方法是
resolveSibling
,它通过解析指定路径的父路径产生其兄弟路径。例如,如果workPath
是/opt/myapp/work
,那么下面的调用
Path tempPath = workPath.resolveSibling("temp");
- 将创建/opt/myapp/temp
resolve
的对立面是relativize
。
二.读写文件
Files
类可以使得普通文件操作变得快捷。例如,可以用下面的方式很容易地读取文件的所有内容:
byte[] bytes = Files.readAllBytes(Paths.get("C:\\Users\\whz\\Desktop\\岗位要求.txt"));
//将文件当做字符串读入
String content = new String(bytes, "UTF-8");
- 如果希望将文件当做行序列读入,可以调用
List<String> lines = Files.readAllLines(
Paths.get("C:\\Users\\whz\\Desktop\\岗位要求.txt"), StandardCharsets.UTF_8);
- 相反地,如果希望写出一个字符串到文件中,可以调用
Files.write(Paths.get("test.txt"),content.getBytes(), StandardOpenOption.APPEND);
- 还可以用下面的语句将一个行的集合写出到文件中
Files.write(Paths.get("test.txt"),lines);
- 这些简便方法适用于处理中等长度的文本文件,如果要处理的文件长度比较大,或者是二进制文件,那么还是应该适用所熟知的输入/输出流或读入器/写出器。
三.创建文件和目录
- 创建新目录可以调用
Files.createDirectories(path);
- 其中,路径中除最后一个部件外,其它部分必须是已存在的。要创建路径中的中间目录,应该使用
Files.createDirectories(path);
- 可以使用下面的语句创建一个空文件
Files.createFile(path);
- 如果文件已经存在了,那么这个调用就会抛出异常。检查文件是否存在和创建文件原子性的,如果文件不存在,该文件就会被创建,并且其它程序在此过程中是无法执行文件创建操作的。
- 有些便捷方法可以用来在给定位置或者系统指定位置创建临时文件或临时目录:
Files.createTempFile(dir,prefix,suffix);
Files.createTempDirectory(dir,prefix);
Files.createTempDirectory(prefix);
- 其中,dir是一个Path对象,prefix和suffix是可以为null的字符串,例如,调用
Files.createTempFile(null,".txt");
可能会返回一个像/tem/293284932493592.txt
这样的路径。
四.复制,移动和删除文件
- 将文件从一个位置复制到另一个位置可以直接调用
Files.copy(fromPath,toPath);
- 移动文件可以调用
Files.move(fromPath,toPath);
- 如果目标路径已经存在,那么复制或移动将失败。如果想要覆盖已有的目标路径可以使用
StandardCopyOption.REPLACE_EXISTING
选项,如果想要复制所有的文件属性,可以使用StandardCopyOption.COPY_ATTRIBUTES
选项,也可以同时选用两个选项。 - 可以将移动操作定义为原子性的,这样就可以保证要么移动操作成功完成,要么源文件继续保持在原来的位置。具有可以使用
StandardCopyOption.ATOMIC_MOVE
选项。 - 还可以将一个输入流复制到
Path
中,这表示想要将输入流存储在硬盘上。类似的,还可以将一个Path
复制到流中,可以使用下面的调用:
Files.copy(inputStream,path);
Files.copy(path,outputStream);
- 删除文件可以调用
Files.delete(path);
该删除方法还可以用来移除空目录。 - 下表展示对文件操作而言可用的选项