[NIO.2] 第三篇 定义 Path 类

一旦确认了文件系统上的一个文件或目录,那么就可以定义一个 Path 类来指向它。定义 Path 类可以使用绝对路径、相对路径、路径中带有一个点号“.”(表示当前目录)、路径中带有两个点“..”(表示上一层目录)等。定义 Path 类最简单的方法是调用辅助类 Paths 的 get() 方法。下面将介绍使用不同的方式来得到 C:\rafaelnadal\tournaments\2009\BNP.txt 文件的 Path 对象。

[b][size=x-large]定义绝对路径[/size][/b]

绝对路径(有时也成为全路径)是指包含了根目录以及所有子目录以及文件名的文件路径。在 NIO.2 中定义绝对路径只需要一行代码,下面的例子定义了 C:\rafaelnadal\tournaments\2009 目录下的 BNP.txt 文件(测试的时候,这个文件有可能不存在):

Path path = Paths.get("C:/rafaelnadal/tournaments/2009/BNP.txt");


get() 方法也支持将文件路径分块。NIO 将会自动重建文件路径。如果你将文件路径分块,那么你就不用再考虑文件路径分隔符。前面的绝对路径例子中的路径可以被分块改写为:

Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt"); 
Path path = Paths.get("C:", "rafaelnadal/tournaments/2009", "BNP.txt");
Path path = Paths.get("C:", "rafaelnadal", "tournaments", "2009", "BNP.txt");


[b][size=x-large]定义根目录的相对路径[/size][/b]

相对路径是绝对路径中的一部分。相对路径经常在创建 web 页面的时候使用。相对路径比绝对路径使用更广泛。定义当前文件存储根目录的相对路径,此路径需要由文件分隔符开始。在下面的例子中,如果当前文件存储的根目录是 C: ,那么文件的绝对路径就是 C:\rafaelnadal\tournaments\2009\BNP.txt:

Path path = Paths.get("/rafaelnadal/tournaments/2009/BNP.txt"); 
Path path = Paths.get("/rafaelnadal","tournaments/2009/BNP.txt");


[b][size=x-large]定义工作目录的相对路径[/size][/b]

当你定义当前工作目录的相对路径的时候,此路径不需要由文件分隔符开始。假设你的工作目录是 C: 根目录下的 /ATP 目录,那么下面的代码片段定义的文件是 C:\ATP\rafaelnadal\tournaments\2009\BNP.txt:

Path path = Paths.get("rafaelnadal/tournaments/2009/BNP.txt");
Path path = Paths.get("rafaelnadal","tournaments/2009/BNP.txt");


[b][size=x-large]使用通配符定义路径[/size][/b]

一般情况下,使用一个点“.”表示当前目录,使用两个点“..”表示父目录这是公认的做法。在 NIO.2 中可以使用 Path.normalize() 方法来消除路径中的冗余(即删除路径中的 /. 或 /..):

Path path = Paths.get("C:/rafaelnadal/tournaments/2009/dummy/../BNP.txt").normalize(); 
Path path = Paths.get("C:/rafaelnadal/tournaments/./2009/dummy/../BNP.txt").normalize();


如果你想看看 normalize() 方法的效果,可以分别打印下面两行代码执行后的路径:

Path noNormalize = Paths.get("C:/rafaelnadal/tournaments/./2009/dummy/../BNP.txt"); 
Path normalize = Paths.get("C:/rafaelnadal/tournaments/./2009/dummy/../BNP.txt").normalize();


使用 System.out.println() 分别打印两个结果,可以看到 normalize 方法移除了冗余信息:

C:\rafaelnadal\tournaments\.\2009\dummy\..\BNP.txt
C:\rafaelnadal\tournaments\2009\BNP.txt


[b][size=x-large]使用 URI 定义路径[/size][/b]

在有的情况下,你可能需要从 URI 创建 Path 对象。可以通过 URI.create() 从给定的字符串创建 URI 对象,然后将 URI 对象作为参数传给 Paths.get() 方法。如果你需要将浏览器的地址栏输入的信息封装进字符串的话,这一招非常有用:

import java.net.URI;

Path path = Paths.get(URI.create("file:///rafaelnadal/tournaments/2009/BNP.txt"));
Path path = Paths.get(URI.create("file:///C:/rafaelnadal/tournaments/2009/BNP.txt"));

[b][size=x-large]
使用 FileSystems.getDefault().getPath() 定义路径[/size][/b]

另一个创建 Path 对象的通用方法是通过 FileSystem 类。首先调用 getDefault() 方法获得默认 FileSystem—— NIO.2 将会生成可以访问默认文件系统的通用对象。然后,调用 getPath() 方法(前面例子中使用的 Paths.get() 方式是这种方式的简写形式):

import java.nio.file.FileSystems; 

Path path = FileSystems.getDefault().getPath("/rafaelnadal/tournaments/2009", "BNP.txt");
Path path = FileSystems.getDefault().getPath("/rafaelnadal/tournaments/2009/BNP.txt");
Path path = FileSystems.getDefault().getPath("rafaelnadal/tournaments/2009", "BNP.txt");
Path path = FileSystems.getDefault().
getPath("/rafaelnadal/tournaments/./2009","BNP.txt").normalize();


[b][size=x-large]获取 Home 目录的路径[/size][/b]

当你在需要获得 Home 目录的路径的时候,可以使用下面的样例代码(返回的 Home 目录依赖不同的机器和不同的操作系统):

Path path = Paths.get(System.getProperty("user.home"), "downloads", "game.exe");


在我的 Windows 7 机器上,将会返回 C:\Users\Terry\downloads\game.exe,在我的 Linux 上,将会返回 /home/Terry/downloads/game.exe。

文章来源:[url]http://www.aptusource.org/2014/03/defining-a-path/[/url]
`java.nio.file.FileSystemAlreadyExistsException` 是 Java NIO 包中定义的一个异常,通常在尝试创建一个文件系统时,该文件系统已经存在的情况下抛出。此异常继承自 `FileSystemException`,用于指示特定于文件系统的错误条件[^1]。 ### 原因 1. **重复创建文件系统**:最常见的原因是尝试通过 `FileSystems.newFileSystem()` 方法创建一个新的文件系统时,指定的文件系统已经存在。例如,当尝试多次挂载同一个 ZIP 文件作为一个文件系统时,如果第一次创建成功,第二次尝试就会触发此异常[^1]。 2. **URI 冲突**:使用相同的 URI 创建不同的文件系统实例时,可能会导致此异常。每个文件系统实例应该由唯一的 URI 标识,重复使用相同的 URI 可能会被视为尝试重新创建已存在的文件系统[^1]。 ### 解决方法 1. **检查文件系统是否存在**:在创建新的文件系统之前,可以通过 `FileSystems.getFileSystem()` 方法检查目标文件系统是否已经存在。如果存在,则可以直接使用已有的实例而不是尝试创建新的[^1]。 2. **使用不同的 URI**:确保每次创建新文件系统时都使用唯一的 URI。即使是要操作相同的物理文件或资源,通过改变 URI 的参数部分也可以让 Java 认为这是不同的文件系统实例[^1]。 3. **关闭不再使用的文件系统**:如果确定某个文件系统不再需要,应该调用其 `close()` 方法来释放资源。这有助于避免因文件系统残留而导致的异常[^1]。 ### 示例代码 以下是一个如何安全地创建文件系统的示例,它首先尝试获取已存在的文件系统实例,如果不存在则创建新的: ```java import java.net.URI; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Paths; public class SafeFileSystemCreation { public static void main(String[] args) { try { // 定义要创建的文件系统的 URI URI uri = URI.create("jar:file:/path/to/your/file.jar"); // 尝试获取已存在的文件系统实例 FileSystem fs = FileSystems.getFileSystem(uri); // 如果文件系统不存在,则创建新的 if (fs == null || !fs.isOpen()) { fs = FileSystems.newFileSystem(uri, Map.of("create", "true")); } // 使用文件系统... System.out.println("File system created or retrieved successfully."); } catch (Exception e) { e.printStackTrace(); } } } ``` 请注意,上述代码中的 `Map.of("create", "true")` 参数取决于具体的文件系统提供者支持的选项,对于某些提供者可能需要不同的参数配置[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值