java.nio.file.Paths原理方法源码
原理
java.nio.file.Paths
类是Java NIO中用于操作文件路径的工具类。它提供了静态方法来创建和操作 java.nio.file.Path
对象。
在Java NIO中,Path
是一个接口,代表了文件系统中的路径。Paths
类提供了一些静态方法来创建 Path
对象。这些方法可以根据给定的字符串或URI来创建路径对象,并且可以将多个部分连接起来形成完整的路径。
Paths
类的原理如下:
- 创建路径:
Paths
类提供了多个静态方法来创建Path
对象。例如,可以使用Paths.get(String)
方法通过给定的字符串创建一个路径对象。还可以使用Paths.get(URI)
方法通过给定的URI创建一个路径对象。 - 操作路径:
Path
对象提供了许多方法来操作路径。可以使用Path.resolve(String)
方法将给定的字符串连接到当前路径上,从而生成一个新的路径。还可以使用Path.getParent()
方法获取当前路径的父路径,使用Path.getFileName()
方法获取当前路径的文件名等等。 - 文件系统操作:
Path
对象还提供了一些方法来进行文件系统操作,例如检查文件是否存在、获取文件属性、创建目录等等。
总之,java.nio.file.Paths
类是一个用于创建和操作文件路径的实用工具类,它基于 java.nio.file.Path
接口提供了一系列静态方法,方便我们在Java程序中进行文件路径相关的操作。
方法用法
这是一个名为 Paths
的 Java 类,提供了用于处理路径的静态方法。
下面对其中的两个方法进行解释:
get(String first, String... more)
此方法将路径字符串(或多个字符串序列)转换为 Path
对象。如果 more
参数没有指定任何元素,则使用 first
参数作为要转换的路径字符串。如果 more
参数指定了一个或多个元素,则将每个非空字符串视为一系列名称元素,并连接它们以形成路径字符串。字符串的连接方式是根据具体的文件系统提供者而定,通常会使用文件系统的分隔符作为分隔符。例如,如果文件系统的分隔符是 “/”,则调用 getPath("/foo","bar","gus")
会将路径字符串 “/foo/bar/gus” 转换为 Path
对象。如果 first
是空字符串且 more
不包含任何非空字符串,则返回表示空路径的 Path
对象。
get(URI uri)
此方法将给定的 URI 转换为 Path
对象。该方法遍历已安装的文件系统提供者,以查找与给定 URI 的方案匹配的提供者。不区分大小写地比较 URI 方案。如果找到提供者,则调用其 getPath
方法来进行转换。
对于默认提供者(由 URI 方案 “file” 标识),给定的 URI 必须具有非空的路径组件,并且查询和片段组件未定义。关于是否允许存在权限组件取决于具体的平台。返回的 Path
与默认文件系统关联。
默认提供者提供了类似于 java.io.File
类的“往返”保证。对于给定的路径 p
,可以保证以下语句成立:
Paths.get(p.toUri()).equals(p.toAbsolutePath())
前提是原始 Path
、URI 和新 Path
都是在同一个 Java 虚拟机中创建的(可能是不同的调用)。其他提供者是否提供任何保证取决于具体的提供者。
这些方法提供了方便的方式来将字符串或 URI 转换为 Path
对象。但需要注意的是,使用这些方法会隐含地假设对默认的文件系统的引用,并限制了调用代码的实用性。如果您希望更灵活地进行操作,可以使用现有的 Path
实例作为锚点,例如:Path dir = ...; Path path = dir.resolve("file");
中文源码
public final class Paths {
private Paths() { }
/**
* 将路径字符串或一系列字符串转换为 {@code Path} 对象。
* 如果 {@code more} 不指定任何元素,则使用 {@code first} 参数的值作为路径字符串进行转换。
* 如果 {@code more} 指定一个或多个元素,则将每个非空字符串(包括 {@code first})视为名称元素序列(参见 {@link Path}),并连接起来形成路径字符串。
* 字符串的连接方式是特定于提供程序的,但通常使用 {@link FileSystem#getSeparator name-separator} 作为分隔符进行连接。
* 例如,如果名称分隔符为 "{@code /}",则调用 {@code getPath("/foo","bar","gus")} 将把路径字符串 "{@code /foo/bar/gus}" 转换为 {@code Path} 对象。
* 如果 {@code first} 是空字符串且 {@code more} 不包含任何非空字符串,则返回表示空路径的 {@code Path} 对象。
*
* <p>通过调用 {@link FileSystems#getDefault default} {@link FileSystem} 的 {@link FileSystem#getPath getPath} 方法获取 {@code Path} 对象。
*
* <p>注意,虽然该方法非常方便,但使用它将意味着默认 {@code FileSystem} 的引用,并限制了调用代码的实用性。因此,不应在旨在灵活重用的库代码中使用它。
* 更灵活的替代方案是使用现有的 {@code Path} 实例作为锚点,例如:
* <pre>
* Path dir = ...
* Path path = dir.resolve("file");
* </pre>
*
* @param first
* 路径字符串或路径字符串的初始部分
* @param more
* 要连接形成路径字符串的附加字符串
*
* @return 结果 {@code Path} 对象
*
* @throws InvalidPathException
* 如果无法将路径字符串转换为 {@code Path} 对象
*
* @see FileSystem#getPath
*/
public static Path get(String first, String... more) {
return FileSystems.getDefault().getPath(first, more);
}
/**
* 将给定的 URI 转换为 {@link Path} 对象。
*
* <p>该方法遍历已安装的 {@link FileSystemProvider#installedProviders() installed} 提供程序,
* 以定位由给定 URI 的 URI {@link URI#getScheme scheme} 标识的提供程序。URI 方案不区分大小写进行比较。
* 如果找到提供程序,则调用其 {@link FileSystemProvider#getPath getPath} 方法来转换 URI。
*
* <p>对于默认提供程序(由 URI 方案 "file" 标识),给定的 URI 具有非空路径组件和未定义的查询和片段组件。
* 是否可以存在权限组件取决于平台。返回的 {@code Path} 与 {@link FileSystems#getDefault default} 文件系统相关联。
*
* <p>默认提供程序提供类似于 {@link java.io.File} 类的<em>往返</em>保证。对于给定的 {@code Path} <i>p</i>,
* 可以保证以下条件成立:
* <blockquote><tt>
* Paths.get(</tt><i>p</i><tt>.{@link Path#toUri() toUri}()).equals(</tt>
* <i>p</i><tt>.{@link Path#toAbsolutePath() toAbsolutePath}())</tt>
* </blockquote>
* 只要原始的 {@code Path}、{@code URI} 和新的 {@code Path} 都是在同一个 Java 虚拟机中创建的(可能是不同的调用)。
* 其他提供程序是否提供任何保证是特定于提供程序的,因此未指定。
*
* @param uri
* 要转换的 URI
*
* @return 结果 {@code Path} 对象
*
* @throws IllegalArgumentException
* 如果 {@code uri} 参数上的前提条件不成立。URI 的格式是特定于提供程序的。
* @throws FileSystemNotFoundException
* 标识的文件系统(由 URI 标识)不存在且无法自动创建,或者由 URI 的方案组件标识的提供程序未安装
* @throws SecurityException
* 如果已安装安全管理器,并且它拒绝访问文件系统的未指定权限
*/
public static Path get(URI uri) {
String scheme = uri.getScheme();
if (scheme == null)
throw new IllegalArgumentException("Missing scheme");
// 检查默认提供程序,以避免加载已安装的提供程序
if (scheme.equalsIgnoreCase("file"))
return FileSystems.getDefault().provider().getPath(uri);
// 尝试找到提供程序
for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
if (provider.getScheme().equalsIgnoreCase(scheme)) {
return provider.getPath(uri);
}
}
throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed");
}
}