第十七章 文件
文件和目录路径
一个 Path 对象表示一个文件或者目录的路径,
是一个跨操作系统(OS)和文件系统的抽象,目的是在构造路径时不必关注底层操作系统
java.nio.file.Paths 类包含一个重载方法 static get(),
该方法接受一系列 String 字符串或一个统一资源标识符(URI)作为参数,并且进行转换返回一个 Path 对象:
Files.exists(p)
Files.isRegularFile(p)
Files.isDirectory(p)
p.isAbsolute()
p.getFileName()
:getFileName() 方法总是返回当前文件名。p.getParent()
p.getRoot()
Files.delete(Path)
; 删除指定文件
Paths.get("C:", "path", "to", "nowhere", "NoFile.txt");
toString: C:\path\to\nowhere\NoFile.txt
Path p = Paths.get("PathInfo.java");
toString: PathInfo.java
Path ap = p.toAbsolutePath();
toString: C:\Users\Bruce\Documents\GitHub\onjava\ExtractedExamples\files\PathInfo.java
选取路径部分片段
// files/PartsOfPaths.java
import java.nio.file.*;
public class PartsOfPaths {
public static void main(String[] args) {
System.out.println(System.getProperty("os.name"));
Path p = Paths.get("PartsOfPaths.java").toAbsolutePath();
for(int i = 0; i < p.getNameCount(); i++)
System.out.println(p.getName(i));
System.out.println("ends with '.java': " +
p.endsWith(".java"));
for(Path pp : p) {
System.out.print(pp + ": ");
System.out.print(p.startsWith(pp) + " : ");
System.out.println(p.endsWith(pp));
}
System.out.println("Starts with " + p.getRoot() + " " + p.startsWith(p.getRoot()));
}
}
通过 getName() 来索引 Path 的各个部分,Path 也实现了 Iterable 接口,因此我们也可 以通过增强的 for-each 进行遍历
使路径以 .java 结尾,使用 endsWith() 方法也会返回 false。这是因为使用 endsWith() 我们可以看到,比较的是整个路径部分,而不会包含文件路径的后缀
遍历 Path 对象并不包含根路径,只有使用 startsWith() 检测根路径时才会返回 true。
路径分析
Files 工具类包含一系列完整的方法用于获得 Path 相关的信息。
// files/PathAnalysis.java
import java.nio.file.*;
import java.io.IOException;
public class PathAnalysis {
static void say(String id, Object result) {
System.out.print(id + ": ");
System.out.println(result);
}
public static void main(String[] args) throws IOException {
System.out.println(System.getProperty("os.name"));
Path p = Paths.get("PathAnalysis.java").toAbsolutePath();
say("Exists", Files.exists(p));
say("Directory", Files.isDirectory(p));
say("Executable", Files.isExecutable(p));
say("Readable", Files.isReadable(p));
say("RegularFile", Files.isRegularFile(p));
say("Writable", Files.isWritable(p));
say("notExists", Files.notExists(p));
say("Hidden", Files.isHidden(p));
say("size", Files.size(p));
say("FileStore", Files.getFileStore(p));
say("LastModified: ", Files.getLastModifiedTime(p));
say("Owner", Files.getOwner(p));
say("ContentType", Files.probeContentType(p));
say("SymbolicLink", Files.isSymbolicLink(p));
if(Files.isSymbolicLink(p))
say("SymbolicLink", Files.readSymbolicLink(p));
if(FileSystems.getDefault().supportedFileAttributeViews().contains("posix"))
say("PosixFilePermissions",
Files.getPosixFilePermissions(p));
}
}
/* 输出:
Windows 10
Exists: true
Directory: false
Executable: true
Readable: true
RegularFile: true
Writable: true
notExists: false
Hidden: false
size: 1631
FileStore: SSD (C:)
LastModified: : 2017-05-09T12:07:00.428366Z
Owner: MINDVIEWTOSHIBA\Bruce (User)
ContentType: null
SymbolicLink: false
*/
在调用最后一个测试方法 getPosixFilePermissions() 之前我们需要确认一下当前文件系统是否支持 Posix 接口,否则会抛出运行时异常。
创建操作
Files.createDirectory(Path);·
用于创建文件夹,即使最后用了加了后缀 123.txt 也是创建名叫 123.txt的文件夹
Files.createFile(Path) 创建文件
删除操作
Files.delete(Paths)
用于删除文件,或者空文件夹
Rmdir.rmdir()
用于删除文件夹
创建流
Files.newDirectoryStream(test).forEach(System.out::println);
Paths的增减修改
通过对 Path 对象增加或者删除一部分来构造一个新的 Path 对象
relativize(Path other) 移除 Path 的根路径
构造此路径和给定路径之间的相对路径
使用 resolve() 添加 Path 的尾路径(不一定是“可发现”的名称)。