查看源代码 Path (Elixir v1.16.2)
此模块提供了用于操作或检索文件系统路径的便利方法。
此模块中的函数可以接收 chardata 作为参数,并将始终返回以 UTF-8 编码的字符串。Chardata 是一个字符串或字符和字符串列表,请参阅 IO.chardata/0
。如果给定一个二进制文件,无论其编码方式如何,其编码都将保留。
此模块中的大多数函数不与文件系统交互,除了少数需要它的函数(例如 wildcard/2
和 expand/1
)。
概要
函数
将给定的路径转换为绝对路径。
从 relative_to
到 path
构建路径。
返回路径的最后一个组件,如果路径不包含任何目录分隔符,则返回路径本身。
返回 path
的最后一个组件,去除 extension
。
返回 path
的目录组件。
将路径转换为绝对路径,扩展任何 .
和 ..
组件以及前导 ~
。
相对于作为第二个参数给定的路径扩展路径,扩展任何 .
和 ..
字符。
返回 path
的最后一个组件的扩展名。
连接路径列表。
连接两个路径。
强制路径为相对路径。
返回 path
相对于 cwd
的直接相对路径。
方便获取相对于当前工作目录的路径。
返回 path
,去除 extension
。
返回 path
,去除 extension
。
返回一个受保护免受目录遍历攻击的相对路径。
返回一个受保护免受目录遍历攻击的相对路径。
根据路径分隔符将路径拆分为列表。
返回路径类型。
根据给定的 glob
表达式遍历路径,并返回匹配列表。
类型
@type t() :: IO.chardata()
路径。
函数
将给定的路径转换为绝对路径。
与 expand/1
不同,不尝试解析 ..
、.
或 ~
。
示例
类 Unix 操作系统
Path.absname("foo")
#=> "/usr/local/foo"
Path.absname("../x")
#=> "/usr/local/../x"
Windows
Path.absname("foo")
#=> "D:/usr/local/foo"
Path.absname("../x")
#=> "D:/usr/local/../x"
从 relative_to
到 path
构建路径。
如果 path
已经是绝对路径,则忽略 relative_to
。另请参见 relative_to/3
。 relative_to
可以是路径或匿名函数,仅在必要时调用该函数,返回路径。
与 expand/2
不同,不尝试解析 ..
、.
或 ~
。
示例
iex> Path.absname("foo", "bar")
"bar/foo"
iex> Path.absname("../x", "bar")
"bar/../x"
返回路径的最后一个组件,如果路径不包含任何目录分隔符,则返回路径本身。
示例
iex> Path.basename("foo")
"foo"
iex> Path.basename("foo/bar")
"bar"
iex> Path.basename("lib/module/submodule.ex")
"submodule.ex"
iex> Path.basename("/")
""
返回 path
的最后一个组件,去除 extension
。
此函数应用于删除可能存在也可能不存在的特定扩展名。
示例
iex> Path.basename("~/foo/bar.ex", ".ex")
"bar"
iex> Path.basename("~/foo/bar.exs", ".ex")
"bar.exs"
iex> Path.basename("~/foo/bar.old.ex", ".ex")
"bar.old"
返回 path
的目录组件。
示例
iex> Path.dirname("/foo/bar.ex")
"/foo"
iex> Path.dirname("/foo/bar/baz.ex")
"/foo/bar"
iex> Path.dirname("/foo/bar/")
"/foo/bar"
iex> Path.dirname("bar.ex")
"."
将路径转换为绝对路径,扩展任何 .
和 ..
组件以及前导 ~
。
示例
Path.expand("/foo/bar/../baz")
#=> "/foo/baz"
相对于作为第二个参数给定的路径扩展路径,扩展任何 .
和 ..
字符。
如果路径已经是绝对路径,则忽略 relative_to
。
请注意,此函数将以 ~
开头的 path
视为绝对路径。
第二个参数首先扩展为绝对路径。
示例
# Assuming that the absolute path to baz is /quux/baz
Path.expand("foo/bar/../bar", "baz")
#=> "/quux/baz/foo/bar"
Path.expand("foo/bar/../bar", "/baz")
#=> "/baz/foo/bar"
Path.expand("/foo/bar/../bar", "/baz")
#=> "/foo/bar"
返回 path
的最后一个组件的扩展名。
对于以点开头且没有扩展名的文件名,它返回空字符串。
有关从路径中提取信息的关联函数,请参见 basename/1
和 rootname/1
。
示例
iex> Path.extname("foo.erl")
".erl"
iex> Path.extname("~/foo/bar")
""
iex> Path.extname(".gitignore")
""
连接路径列表。
此函数应用于将路径列表转换为路径。请注意,在连接时会删除任何尾部斜杠。
如果给定的路径列表为空,则引发错误。
示例
iex> Path.join(["~", "foo"])
"~/foo"
iex> Path.join(["foo"])
"foo"
iex> Path.join(["/", "foo", "bar/"])
"/foo/bar"
连接两个路径。
正确的路径将始终扩展为其相对格式,并且在连接时会删除任何尾部斜杠。
示例
iex> Path.join("foo", "bar")
"foo/bar"
iex> Path.join("/foo", "/bar/")
"/foo/bar"
此模块中的函数支持 chardata,因此给出列表将将其视为单个实体
iex> Path.join("foo", ["bar", "fiz"])
"foo/barfiz"
iex> Path.join(["foo", "bar"], "fiz")
"foobar/fiz"
如果您需要连接路径列表,请使用 join/1
。
强制路径为相对路径。
如果给定绝对路径,则从其根组件中剥离。
示例
类 Unix 操作系统
Path.relative("/usr/local/bin") #=> "usr/local/bin"
Path.relative("usr/local/bin") #=> "usr/local/bin"
Path.relative("../usr/local/bin") #=> "../usr/local/bin"
Windows
Path.relative("D:/usr/local/bin") #=> "usr/local/bin"
Path.relative("usr/local/bin") #=> "usr/local/bin"
Path.relative("D:bar.ex") #=> "bar.ex"
Path.relative("/bar/foo.ex") #=> "bar/foo.ex"
返回 path
相对于 cwd
的直接相对路径。
换句话说,此函数尝试返回一条路径,以便 Path.expand(result, cwd)
指向 path
。此函数旨在尽可能返回相对路径,但不能保证
如果两个路径都是相对的,则始终返回相对路径
如果两个路径都是绝对的,则如果它们共享一个公共前缀,则可能会返回相对路径。您可以传递
:force
选项以强制此函数向上遍历,但即使那样也不能保证返回相对路径(例如,如果绝对路径属于 Windows 上的不同驱动器)如果给定路径的混合,结果将始终匹配给定的
path
(第一个参数)
此函数扩展 .
和 ..
条目,而无需遍历文件系统,因此它假定路径之间没有符号链接。有关更安全的替代方法,请参见 safe_relative_to/2
。
选项
:force
- (自 v1.16.0 起为布尔值)如果为true
,则强制返回相对路径,方法是向上遍历路径。除了 Windows 上的路径位于不同卷中。默认为false
。
示例
使用相对 cwd
如果两个路径都是相对的,则计算最小路径
Path.relative_to("tmp/foo/bar", "tmp") #=> "foo/bar"
Path.relative_to("tmp/foo/bar", "tmp/foo") #=> "bar"
Path.relative_to("tmp/foo/bar", "tmp/bat") #=> "../foo/bar"
如果给定绝对路径和相对 cwd
,则将其返回为
Path.relative_to("/usr/foo/bar", "tmp/bat") #=> "/usr/foo/bar"
使用绝对 cwd
如果两个路径都是绝对的,则如果可能,计算相对路径,而无需向上遍历
Path.relative_to("/usr/local/foo", "/usr/local") #=> "foo"
Path.relative_to("/usr/local/foo", "/") #=> "usr/local/foo"
Path.relative_to("/usr/local/foo", "/etc") #=> "/usr/local/foo"
Path.relative_to("/usr/local/foo", "/usr/local/foo") #=> "."
Path.relative_to("/usr/local/../foo", "/usr/foo") #=> "."
Path.relative_to("/usr/local/../foo/bar", "/usr/foo") #=> "bar"
如果 :force
设置为 true
,则路径向上遍历
Path.relative_to("/usr", "/usr/local", force: true) #=> ".."
Path.relative_to("/usr/foo", "/usr/local", force: true) #=> "../foo"
Path.relative_to("/usr/../foo/bar", "/etc/foo", force: true) #=> "../../foo/bar"
如果给定相对路径,则假定它相对于给定路径,因此路径将返回,并扩展了 "." 和 ".."。
Path.relative_to(".", "/usr/local") #=> "."
Path.relative_to("foo", "/usr/local") #=> "foo"
Path.relative_to("foo/../bar", "/usr/local") #=> "bar"
Path.relative_to("foo/..", "/usr/local") #=> "."
Path.relative_to("../foo", "/usr/local") #=> "../foo"
方便获取相对于当前工作目录的路径。
如果由于某种原因无法检索当前工作目录,则此函数返回给定的 path
。
检查 relative_to/3
以了解支持的选项。
返回 path
,去除 extension
。
示例
iex> Path.rootname("/foo/bar")
"/foo/bar"
iex> Path.rootname("/foo/bar.ex")
"/foo/bar"
返回 path
,去除 extension
。
此函数应用于删除可能存在也可能不存在的特定扩展名。
示例
iex> Path.rootname("/foo/bar.erl", ".erl")
"/foo/bar"
iex> Path.rootname("/foo/bar.erl", ".ex")
"/foo/bar.erl"
返回一个受保护免受目录遍历攻击的相对路径。
通过消除 ..
和 .
组件来清理给定的相对路径。
此函数检查在扩展这些组件后,路径是否仍然“安全”。如果以下两者之一为真,则路径被视为不安全
路径不是相对路径,例如
"/foo/bar"
。..
组件将导致路径向上遍历到relative_to
根目录之上。路径中的符号链接指向
cwd
根目录之上的某处。
示例
iex> Path.safe_relative("foo")
{:ok, "foo"}
iex> Path.safe_relative("deps/my_dep/app.beam")
{:ok, "deps/my_dep/app.beam"}
iex> Path.safe_relative("deps/my_dep/./build/../app.beam", File.cwd!())
{:ok, "deps/my_dep/app.beam"}
iex> Path.safe_relative("my_dep/../..")
:error
iex> Path.safe_relative("/usr/local", File.cwd!())
:error
返回一个受保护免受目录遍历攻击的相对路径。
有关此 API 的非弃用版本,请参见 safe_relative/2
。
根据路径分隔符将路径拆分为列表。
如果给定空字符串,则返回空列表。
在 Windows 上,路径将在 "\"
和 "/"
分隔符上拆分,并且如果有驱动器号,则始终以小写形式返回。
示例
iex> Path.split("")
[]
iex> Path.split("foo")
["foo"]
iex> Path.split("/foo/bar")
["/", "foo", "bar"]
@spec type(t()) :: :absolute | :relative | :volumerelative
返回路径类型。
示例
类 Unix 操作系统
Path.type("/") #=> :absolute
Path.type("/usr/local/bin") #=> :absolute
Path.type("usr/local/bin") #=> :relative
Path.type("../usr/local/bin") #=> :relative
Path.type("~/file") #=> :relative
Windows
Path.type("D:/usr/local/bin") #=> :absolute
Path.type("usr/local/bin") #=> :relative
Path.type("D:bar.ex") #=> :volumerelative
Path.type("/bar/foo.ex") #=> :volumerelative
根据给定的 glob
表达式遍历路径,并返回匹配列表。
通配符看起来像普通的路径,除了以下“通配符字符”以特殊方式解释
?
- 匹配一个字符。*
- 匹配任意数量的字符,直到文件名结束、下一个点或下一个斜杠。**
- 作为单个模式使用的两个相邻*
将匹配所有文件以及零个或多个目录和子目录。[char1,char2,...]
- 匹配列表中的任意字符;用连字符分隔的两个字符将匹配一个字符范围。 不要在逗号前后添加空格,否则它将匹配包含空格字符本身的路径。{item1,item2,...}
- 匹配其中一个备选项。 不要在逗号前后添加空格,否则它将匹配包含空格字符本身的路径。
其他字符代表自身。 只有在相同位置具有完全相同字符的路径才会匹配。 请注意,匹配区分大小写:"a"
不会匹配 "A"
。
目录分隔符必须始终写为 /
,即使在 Windows 上也是如此。 您可以在调用此函数之前调用 Path.expand/1
来规范化路径。
以 \\
开头的字符将失去其特殊含义。 请注意,在字符串字面量中,\\
必须写为 \\\\
。 例如,"\\\\?*"
将匹配以 ?.
开头的任何文件名。
默认情况下,模式 *
和 ?
不会匹配以点 .
开头的文件。 请参阅下面“选项”部分中的 :match_dot
选项。
选项
:match_dot
- (布尔值) 如果为false
,则特殊通配符*
和?
不会匹配以点 (.
) 开头的文件。 如果为true
,则以.
开头的文件将不会被特殊对待。 默认值为false
。
示例
假设您有一个名为 projects
的目录,其中包含三个 Elixir 项目:elixir
、ex_doc
和 plug
。 您可以找到每个项目 ebin
目录中的所有 .beam
文件,如下所示
Path.wildcard("projects/*/ebin/**/*.beam")
如果您想搜索 .beam
和 .app
文件,您可以执行以下操作
Path.wildcard("projects/*/ebin/**/*.{beam,app}")