使用Path接口在文件和目录路径上操作。
使用Files类检查、读取、删除、复制、移动、管理文件或目录的元数据。
NIO.2
- Java 的第一个版本中java.io包的File类缺乏对File文件属性的支持
- java1.4在 java.nio 包中引入了NIO(非阻塞输入/输出) API,实现了通道、缓冲和新的字符集等新功能(这个API 并没有完全解决 Java.io包的问题)
- 在 java7中,NIO.2 API 被添加到了 java.nio.file 包中(实际上,由于这是一个新包,NIO.2并不是NIO API的更新,而且它们关注的是不同的东西)
NIO.2包的作用
- NIO. 2为访问文件和文件系统、符号链接、互操作性和异常等提供了更好的支持。
- File、 Path、 Paths 和 Files 的主要类旨在提供一种处理文件的更简单方法,并作为 java.io 的替代品。文件类。
关于Path和Paths
- Path是用于处理路径的方法的接口
- Paths是具有创建 Path 对象的静态方法的工具类
其只有2种静态方法获得Path,一个是通过String对象,一个是通过URI
Path接口
Path 接口定义了一个对象,它表示文件或目录的路径。
考虑到路径在不同文件系统之间变化,Path使得Java 可以透明地处理不同平台之间的不同实现
- 例如Win和Unix区别
1.基于Windows的系统不区分大小写,而基于Unix的系统区分大小写。
2.在基于Windows的系统中,路径由反斜杠分隔。在基于Unix的系统中,使用正斜杠。
3.在基于Windows的系统中,根路径是驱动器号(通常是c:\)。在基于Unix的系统中,它是一个正斜杠(/)。
4.在基于Windows的系统中,绝对路径以驱动器号开头(如c:\temp\file.txt)。在基于Unix的系统中,它以正斜杠开始(如/temp/file.txt)。
获得Path接口的实现类实例
通过Paths工具类获得Path
java.nio.file.Paths类提供了两个方法来创建 Path 对象
static Path get(String first, String... more)
static Path get(URI uri)
- Paths.get(String first, String... more)创建Path
// With an absolute path in windows
Path pathWin = Paths.get("c:\\temp\\file.txt");
// With an absolute path in unix
Path pathUnix = Paths.get("/temp/file.txt");
// With a relative path
Path pathRelative = Paths.get("file.txt");
//Using the varargs parameter
// (the separator is inserted automatically)
Path pathByParts = Paths.get("c:", "temp", "file.txt");
- Paths.get(URI uri)创建Path
必须使用一个 java.net.uri 实例。因为我们使用的是文件,所以 URI 模式必须是 file://:
try {
Path fileURI = Paths.get(new URI("file:///c:/temp/file.txt"));
} catch (URISyntaxException e) {
//This checked exception is thrown by the URI constructor
}
如果不想捕获 URISyntaxException,可以使用静态方法 URI.create (String)。它用 IllegalArgumentException (RuntimeException的子类)包装 URISyntaxException(Exception的子类) 异常
注意三个斜杠。file:///表示绝对路径(file://模式加上根目录的另一个/)。我们可以借助toAbsolutionPath()方法来测试这一点,该方法返回路径对象的绝对路径表示:
Path fileURI = Paths.get(URI.create("file:///file.txt"));
System.out.println(fileURI.toAbsolutePath());
C:\file.txt // in Windows-based systems
/file.txt // Or in Unix-based systems
- Mac中
- Win中
其JDK的源码都不一样,Path接口的实现不同
通过File类创建Path
File file = new File("/file.txt");
Path path = file.toPath();
Path路径组成
Path 对象的绝对路径表示有一个根组件(c: 或/)和一系列名称,名称由一个(向前或向后)斜杠分隔。
这些名称表示导航到目标文件或目录所需的目录。序列中的最后一个名称表示目标文件或目录的名称。
- 例如c:\temp\dir1\file.txt (或者它的等效 Unix/temp/dir1/file.txt)
Root: c:\ (or /)
Name 1: temp
Name 2: dir1
Name 3: file.txt
Path 对象有一些方法来获取这些信息。除了 toString ()和 getNameCount () ,这些方法都返回一个 Path 对象
Path path = Paths.get("C:\\temp\\dir1\\file.txt");
// Or Path path = Paths.get("/temp/dir1/file.txt");
System.out.println("toString(): " + path.toString());
System.out.println("getFileName(): " + path.getFileName());
System.out.println("getNameCount(): " +path.getNameCount());
// Indexes start from zero
System.out.println("getName(0): " + path.getName(0));
System.out.println("getName(1): " + path.getName(1));
System.out.println("getName(2): " + path.getName(2));
// subpath(beginIndex, endIndex) from beginIndex to endIndex-1
System.out.println("subpath(0,2): " + path.subpath(0,2));
System.out.println("getParent(): " + path.getParent());
System.out.println("getRoot(): " + path.getRoot());
向 getName ()和 subpath ()传递无效索引将引发 IllegalArgumentException (RuntimeException)
其输出结果应为
toString(): C:\temp\dir1\file.txt // Or /temp/dir1/file.txt
getFileName(): file.txt
getNameCount(): 3
getName(0): temp
getName(1): dir1
getName(2): file.txt
subpath(0,2): temp\dir1 // Or temp/dir1
getParent(): C:\temp\dir1 // Or /temp/dir1
getRoot(): C:\ // Or /
- 如果路径被指定为相对路径(并且假设这段代码是在 c: temp 目录中执行的) :
Path path = Paths.get("dir1\\file.txt");// Or dir1/file.txt
System.out.println("toString(): " + path.toString());
System.out.println("getFileName(): " + path.getFileName());
System.out.println("getNameCount(): " + path.getNameCount());
System.out.println("getName(0): " + path.getName(0));
System.out.println("getName(1): " + path.getName(1));
System.out.println("subpath(0,2): " + path.subpath(0,2));
System.out.println("getParent(): " + path.getParent());
System.out.println("getRoot(): " + path.getRoot());
结果为
toString(): dir1\file.txt // Or dir1/file.txt
getFileName(): file.txt
getNameCount(): 2
getName(0): dir1
getName(1): file.txt
subpath(0,2): dir1\file.txt // Or dir1/file.txt
getParent(): dir1
getRoot(): null
- 当使用路径时,可以使用:
./引用当前目录
../引用父级目录
可以使用 normalize ()方法来消除冗余,使得路径现实正常化
Path path = Paths.get("/temp/dir1/../file.txt");
System.out.println(path); // /temp/dir1/../file.txt
Path path2 = path.normalize();
System.out.println(path2); // /temp/file.txt
- normalize()弊端
此方法不访问文件系统以知道是否存在文件,因此删除。.以及路径的前面名称可能导致路径不再引用原始文件。当前一个名称是一个符号链接(对另一个文件的引用)时,就会发生这种情况
toRealPath()方法
//返回现有文件的真实路径。
Path toRealPath(LinkOption... options) throws IOException
- 相比较normalize()的好处
1.默认情况下如果以LinkOption.NOFOLLOW_LINKS作为参数传递,则符号链接后面不跟(默认情况下是这样)。
2.如果路径是相对的,则返回绝对路径。
3.它返回一个删除了冗余元素(如果有的话)的路径。
Files类
注意点:
- java.nio.file.Files对文件和目录进行常见操作的静态方法
public方法全部为static - 不同于java.io.File类,Files方法都使用Path对象
全部入参都使用Path
常用方法
- 检查一个路径是否可读(如果文件不存在或者 JVM 没有访问它的特权,那么这个路径就不可读)
static boolean isReadable(Path path)
- 检查一个路径是否可写(如果文件不存在或者 JVM 没有访问它的特权,那么这个路径就不可写)
static boolean isWritable(Path path)
- 检查一个文件是否存在并可执行:
static boolean isExecutable(Path path)
- 检查两个路径是否引用同一个文件(如果一个路径表示一个符号链接,则很有用)。如果两个 Path 对象都相等,那么这个方法返回 true,而不检查文件是否存在
static boolean isSameFile(Path path,Path path2) throws IOException
- 将整个文件加载到内存中(只对小文件有用)
static byte[] readAllBytes(Path path)
throws IOException
static List<String> readAllLines(Path path)
throws IOException
static List<String> readAllLines(Path path, Charset cs)
throws IOException
- 另一种有效的方式读取文件
static BufferedReader newBufferedReader(Path path)
throws IOException
static BufferedReader newBufferedReader(Path path, Charset cs)
throws IOException
- 删除文件/目录的方法
1.删除失败(包括文件不存在)抛出异常
static void delete(Path path) throws IOException
失败时抛出异常
try {
Files.delete(Paths.get("/temp/dir1/file.txt"));
Files.delete(Paths.get("/temp/dir1"));
} catch (NoSuchFileException nsfe) {
// If the file/directory doesn't exists
} catch (DirectoryNotEmptyException dnee) {
// To delete a directory, it must be empty,
// otherwise, this exception is thrown
} catch (IOException ioe) {
// File permission or other problems
}
2.(不管是否删除均不会抛出异常,只会返回true、false)
static boolean deleteIfExists(Path path) throws IOException
文件被删除,这个方法返回 true; 如果文件因为不存在而无法删除,这个方法返回 false。换句话说,与第一个方法不同,这个方法不会抛出 NoSuchFileException (但是它仍然会抛出一个 DirectoryNotEmptyException 和一个 IOException,用于其他问题)
try {
Files.deleteIfExists(Paths.get("/temp/dir1/file.txt"));
} catch (DirectoryNotEmptyException dnee) {
// To delete a directory, it must be empty,
} catch (IOException ioe) {
// File permission or other problems
}
- 复制文件/目录
static Path copy(Path source, Path target,CopyOption... options) throws IOException
它返回目标文件的路径,当复制一个目录时,它的内容不会被复制
管理元数据
元数据向我们提供有关文件或目录的信息,比如它的大小、权限、创建日期等。这些信息称为属性,其中一些属性是系统相关的
Files类从Path对象获取属性
- 文件的大小(以字节为单位)
static long size(Path path) throws IOException
- 文件是否是目录
static boolean isDirectory(Path path, LinkOption... options)
- 文件是否为常规文件。
static boolean isRegularFile(Path path, LinkOption... options)
- 文件是否为符号链接
static boolean isSymbolicLink(Path path)
- 文件是否隐藏
static boolean isHidden(Path path) throws IOException
- 返回或更新文件上次修改的时间
static FileTime getLastModifiedTime(Path path,
LinkOption... options) throws IOException
static Path setLastModifiedTime(Path path,
FileTime time) throws IOException
- 返回或更新文件的所有者
static UserPrincipal getOwner(Path path,
LinkOption... options) throws IOException
static Path setOwner(Path path,
UserPrincipal owner) throws IOException
//TODO
总结
- java.nio.file的主要类是Path、Paths和Files。它们旨在替代java.io.File类。
- Path接口定义一个表示文件或目录路径的对象。
Path提供了创建路径对象的方法。 - 路径对象的绝对路径表示有一个根组件(c:\或/)和一系列名称,名称之间用斜杠(正斜杠或反斜杠)隔开。
Path接口具有获取路径元素、规范化路径和获取路径属性的方法(isAbsolute()、getFileSystem()等)。它还扩展Comparable并实现equals(),以测试相等性。 - java.nio.file.Files类具有用于对文件和目录执行常见操作的静态方法。与java.io.File类不同,文件的所有方法都使用Path对象。
Comments | 0 条评论