本文主要介绍一下 path 库的使用。
path 库的 pub 仓库地址:path
1. path 库的介绍
path 是针对 Dart 语言设计的一个全面的、跨平台的路径操作库。path 插件提供了操作路径的常用操作:加入、拆分、规范化等。
2. path 库的使用
2.1 添加依赖
dependencies:
path: ^1.8.1
path 的版本号参考:Stable versions of path
2.2 导包
import 'package:path/path.dart' as p;
/// 也可以不使用前缀的方式,直接用全路径的方式导入。本文后面的例子以使用前缀的方式。
import 'package:path/path.dart';
2.3 最常用的函数:join()
path 库最常用方法是顶级函数 join()。join 函数会根据你当前的工作目录和使用的主机平台的路径样式(POSIX
,Windows
,或 URLs
)来将给定的路径连接成单个路径,并返回。
- POSIX 风格的路径使用
/
(正斜杠)作为分隔符。绝对路径以/
开头。适用于UNIX
、Linux
、Mac OS X
等。 - Windows 风格的路径使用
\
(反斜杠)作为分隔符。绝对路径以驱动器号和冒号开头(例如,C:
),或者两个反斜杠(\\
)作为 UNC 路径。 - URLs 不是文件系统路径,path 支持它是为了更容易在浏览器中操作 URL 路径。URLs 使用
/
(正斜杠)作为分隔符。绝对路径可以以一个协议和可选的主机名(例如。https://dart.dev
,文件://
),也可以在尾部加一个/
。
代码片段:
p.join('directory', 'file.txt');
调用 join() 会以当前平台的目录分隔符连接“directory”和“file.txt”。join 函数会返回拼接后的路径 String。
以我使用的 mac 电脑为例子,会使用正斜杠 /
分隔符来连接,如果将 p.join('directory', 'file.txt')
的结果打印出来会得到如下的一个 String:
directory/file.txt
如果你想指定使用某个特定平台的路径分隔符,你可以创建一个 Context
并给指定一个 Style
:
import 'package:path/path.dart' as p;
String getContextPathString() {
var context = p.Context(style: p.Style.windows);
return context.join('directory', 'file.txt');
}
此时,输出 context.join('directory', 'file.txt')
的结果会得到如下 String:
directory\file.txt
👉 使用 join 的一些规则
1.join() 最多只能接收 8
个参数。
来看看 join 函数的定义就知道了:
/// 使用了位置可选参数来声明 part2 到 part 8 参数
String join(String part1,
[String? part2,
String? part3,
String? part4,
String? part5,
String? part6,
String? part7,
String? part8]) =>
context.join(part1, part2, part3, part4, part5, part6, part7, part8);
2.如果任何 part 参数以路径分隔符结尾,则会被忽略掉
代码片段:
/// 我们在 directory 后面加了一个正斜杠
p.join('directory/', 'to', 'foo');
//// 打印结果为:directory/to/foo
3.如果某个 part 参数使用了绝对路径,那么它之前的 part 参数都将被忽略
代码片段:
/// 我们在第二个参数使用了一个绝对路径 /to
p.join('directory', '/to', 'foo');
/// 打印结果为:/to/foo
2.4 joinAll() 函数
joinAll() 函数的作用和路径的生成规则与 join() 函数是一样的,只是需要的参数不同。
joinAll() 接收一个 Iterable<String>
参数。
代码片段:
p.joinAll(['path', 'to', 'foo']); // 返回路径 'path/to/foo'
p.joinAll(['path/', 'to', 'foo']); // 返回路径 'path/to/foo
p.joinAll(['path', '/to', 'foo']); // 返回路径 '/to/foo'
👉 Tips
对于固定数量的 part 路径,通常使用 join() 函数。
2.5 dirname(String path) 函数
作用:获取最后一个分隔符之前的 path 部分。
代码片段:
p.dirname('path/to/foo.dart'); // 返回 'path/to'
p.dirname('path/to'); // 返回 'path'
/// 末尾的分隔符会被忽略
p.dirname('path/to/'); // 返回 'path'
/// 如果绝对路径且仅包含根目录,则返回根目录
p.dirname('/'); // 返回 '/' (posix)
p.dirname('c:\'); // 返回 'c:\' (windows)
/// 如果相对路径没有目录,则 '.' 被退回
p.dirname('foo'); // 返回 '.'
p.dirname(''); // 返回 '.'
2.6 normalize(String path) 标准化路径
normalize() 通过处理 ..
和 .
来简化路径,并且会尽可能地删除多余的路径分隔符。
代码片段:
p.normalize('path/./to/..//file.text'); // 返回 'path/file.txt'
2.7 canonicalize(String path) 规范化路径
如果两个输入路径都指向同一位置时,调用 canonicalize() 会保证返回相同的路径。 与 normalize() 不同,它尽可能返回 绝对路径
,并在 Windows 上规范化 ASCII 大小写。
2.8 basename(String path) 函数
作用:获取最后一个分隔符之后的 path 部分。
代码片段:
p.basename('path/to/foo.dart'); // 返回 'foo.dart'
p.basename('path/to'); // 返回 'to'
/// 末尾的分隔符会被忽略
p.basename('path/to/'); // 返回 'to'
2.9 basenameWithoutExtension(String path) 函数
作用:获取最后一个分隔符之后的 path 部分,并且没有任何文件后缀名。
代码片段:
p.basenameWithoutExtension('path/to/foo.dart'); // 返回 'foo'
/// 末尾的分隔符会被忽略
p.basenameWithoutExtension('path/to/foo.dart/'); // 返回 'foo'
2.10 extension(String path, [int level = 1]) 函数
作用:获取 path 的文件扩展名:basename 的最后一部分,包括 .
本身。
代码片段:
p.extension('path/to/foo.dart'); // 返回 '.dart'
p.extension('path/to/foo'); // 返回 ''
p.extension('path.to/foo'); // 返回 ''
p.extension('path/to/foo.dart.js'); // 返回 '.js'
/// 如果文件名以 `.` 开头,则不视为扩展名
p.extension('~/.bashrc'); // 返回 ''
p.extension('~/.notes.txt'); // 返回 '.txt'
/// 可以指定返回包含多个 . 的扩展名
p.extension('foo.bar.dart.js', 2); // 返回 '.dart.js
p.extension('foo.bar.dart.js', 3); // 返回 '.bar.dart.js'
p.extension('path/to/foo.bar.dart.js', 2); // -> '.dart.js'
/// 如果指定的数量超过了总的 . 数,则返回完整的扩展名
p.extension('foo.bar.dart.js', 10); // 返回 '.bar.dart.js'
/// 注意,指定的数量不能为 0,否者会出现 RangeError 错误
2.11 rootPrefix(String path) 函数
作用:如果是绝对路径,则返回 path 的根,如果是相对路径,则返回空字符串。
// Unix
p.rootPrefix('path/to/foo'); // -> ''
p.rootPrefix('/path/to/foo'); // -> '/'
// Windows
p.rootPrefix(r'path\to\foo'); // -> ''
p.rootPrefix(r'C:\path\to\foo'); // -> r'C:\'
p.rootPrefix(r'\\server\share\a\b'); // -> r'\\server\share'
// URL
p.rootPrefix('path/to/foo'); // -> ''
p.rootPrefix('https://dart.dev/path/to/foo');// -> 'https://dart.dev'
2.12 split(String path) 函数
作用:使用当前平台的分隔符对 path 进行拆分。
代码片段:
p.split('path/to/foo'); // 返回 ['path', 'to', 'foo']
/// 拆分前路径不会执行 normalize 操作
p.split('path/../foo'); // 返回 ['path', '..', 'foo']
/// 如果 path 是绝对的,则根目录将是数组中的第一个元素
// Unix
p.split('/path/to/foo'); // 返回 ['/', 'path', 'to', 'foo']
// Windows
p.split(r'C:\path\to\foo'); // 返回 [r'C:\', 'path', 'to', 'foo']
p.split(r'\\server\share\path\to\foo');// 返回 [r'\\server\share', 'foo', 'bar', 'baz']
// Browser
p.split('https://dart.dev/path/to/foo');// 返回 ['https://dart.dev', 'path', 'to', 'foo']
2.13 relative(String path, {String? from}) 函数
作用:尝试将 path 转换为当前目录的等效相对路径。
代码片段:
// Given current directory is /root/path:
p.relative('/root/path/a/b.dart'); // 返回 'a/b.dart'
p.relative('/root/other.dart'); // 返回 '../other.dart'
/// 如果传递了 [from] 参数,则 [path] 相对于该参数
p.relative('/root/path/a/b.dart', from: '/root/path'); // 返回 'a/b.dart'
p.relative('/root/other.dart', from: '/root/path');// 返回 '../other.dart'
2.14 isWithin(String parent, String child)
作用:如果 child
是 parent
下面的路径,则返回 true
,否则返回 false
。
代码片段:
p.isWithin('/root/path', '/root/path/a'); // -> true
p.isWithin('/root/path', '/root/other'); // -> false
p.isWithin('/root/path', '/root/path') // -> false
2.15 equals(String path1, String path2)
作用:如果 path1 指向与 path2 相同的位置,则返回 true
,否则 false
。
代码片段:
path.equals('a/b', 'a/b') -> true
2.16 withoutExtension(String path) 函数
作用:从 path 的最后一部分删除末尾扩展名。
代码片段:
p.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
2.17 setExtension(String path, String extension) 函数
作用:将 path 末尾的扩展名设置为 extension
参数的值。如果 path 末尾没有扩展名,会将 extension
的值添加到末尾。
代码片段:
p.setExtension('path/to/foo.dart', '.js') // 返回 'path/to/foo.js'
p.setExtension('path/to/foo.dart.js', '.map')// 返回 'path/to/foo.dart.map'
p.setExtension('path/to/foo', '.js') // 返回 'path/to/foo.js'
2.18 fromUri
作用:返回 uri 表示的路径,可以是 String 或 Uri。
代码片段:
/// 对于 POSIX and Windows styles, [uri] 必须是 `file:` URI。
/// 对于 URL style, 将会把 [uri] 转换为一个 string.
// POSIX
p.fromUri('file:///path/to/foo') // -> '/path/to/foo'
// Windows
p.fromUri('file:///C:/path/to/foo') // -> r'C:\path\to\foo'
// URL
p.fromUri('https://dart.dev/path/to/foo')// -> 'https://dart.dev/path/to/foo'
/// If [uri] is relative, a relative path will be returned.
p.fromUri('path/to/foo'); // -> 'path/to/foo'
2.19 prettyUri
作用:可以传递一个 String 或者 Uri,将返回简洁、易读的 uri。
代码片段:
// POSIX at "/root/path"
p.prettyUri('file:///root/path/a/b.dart'); // -> 'a/b.dart'
p.prettyUri('https://dart.dev/'); // -> 'https://dart.dev'
// Windows at "C:\root\path"
p.prettyUri('file:///C:/root/path/a/b.dart'); // -> r'a\b.dart'
p.prettyUri('https://dart.dev/'); // -> 'https://dart.dev'
// URL at "https://dart.dev/root/path"
p.prettyUri('https://dart.dev/root/path/a/b.dart'); // -> r'a/b.dart'
p.prettyUri('file:///root/path'); // -> 'file:///root/path'