查看源代码 Path (Elixir v1.16.2)

此模块提供了用于操作或检索文件系统路径的便利方法。

此模块中的函数可以接收 chardata 作为参数,并将始终返回以 UTF-8 编码的字符串。Chardata 是一个字符串或字符和字符串列表,请参阅 IO.chardata/0。如果给定一个二进制文件,无论其编码方式如何,其编码都将保留。

此模块中的大多数函数不与文件系统交互,除了少数需要它的函数(例如 wildcard/2expand/1)。

概要

类型

t()

路径。

函数

将给定的路径转换为绝对路径。

relative_topath 构建路径。

返回路径的最后一个组件,如果路径不包含任何目录分隔符,则返回路径本身。

返回 path 的最后一个组件,去除 extension

返回 path 的目录组件。

将路径转换为绝对路径,扩展任何 ... 组件以及前导 ~

相对于作为第二个参数给定的路径扩展路径,扩展任何 ... 字符。

返回 path 的最后一个组件的扩展名。

连接路径列表。

连接两个路径。

强制路径为相对路径。

返回 path 相对于 cwd 的直接相对路径。

方便获取相对于当前工作目录的路径。

返回 path,去除 extension

返回 path,去除 extension

返回一个受保护免受目录遍历攻击的相对路径。

返回一个受保护免受目录遍历攻击的相对路径。

根据路径分隔符将路径拆分为列表。

返回路径类型。

根据给定的 glob 表达式遍历路径,并返回匹配列表。

类型

@type t() :: IO.chardata()

路径。

函数

@spec absname(t()) :: binary()

将给定的路径转换为绝对路径。

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"
链接到此函数

absname(path, relative_to)

查看源代码
@spec absname(t(), t() | (-> t())) :: binary()

relative_topath 构建路径。

如果 path 已经是绝对路径,则忽略 relative_to。另请参见 relative_to/3relative_to 可以是路径或匿名函数,仅在必要时调用该函数,返回路径。

expand/2 不同,不尝试解析 ...~

示例

iex> Path.absname("foo", "bar")
"bar/foo"

iex> Path.absname("../x", "bar")
"bar/../x"
@spec basename(t()) :: binary()

返回路径的最后一个组件,如果路径不包含任何目录分隔符,则返回路径本身。

示例

iex> Path.basename("foo")
"foo"

iex> Path.basename("foo/bar")
"bar"

iex> Path.basename("lib/module/submodule.ex")
"submodule.ex"

iex> Path.basename("/")
""
链接到此函数

basename(path, extension)

查看源代码
@spec basename(t(), t()) :: binary()

返回 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"
@spec dirname(t()) :: binary()

返回 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")
"."
@spec expand(t()) :: binary()

将路径转换为绝对路径,扩展任何 ... 组件以及前导 ~

示例

Path.expand("/foo/bar/../baz")
#=> "/foo/baz"
链接到此函数

expand(path, relative_to)

查看源代码
@spec expand(t(), t()) :: binary()

相对于作为第二个参数给定的路径扩展路径,扩展任何 ... 字符。

如果路径已经是绝对路径,则忽略 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"
@spec extname(t()) :: binary()

返回 path 的最后一个组件的扩展名。

对于以点开头且没有扩展名的文件名,它返回空字符串。

有关从路径中提取信息的关联函数,请参见 basename/1rootname/1

示例

iex> Path.extname("foo.erl")
".erl"

iex> Path.extname("~/foo/bar")
""

iex> Path.extname(".gitignore")
""
@spec join([t(), ...]) :: binary()

连接路径列表。

此函数应用于将路径列表转换为路径。请注意,在连接时会删除任何尾部斜杠。

如果给定的路径列表为空,则引发错误。

示例

iex> Path.join(["~", "foo"])
"~/foo"

iex> Path.join(["foo"])
"foo"

iex> Path.join(["/", "foo", "bar/"])
"/foo/bar"
@spec join(t(), t()) :: binary()

连接两个路径。

正确的路径将始终扩展为其相对格式,并且在连接时会删除任何尾部斜杠。

示例

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

@spec relative(t()) :: binary()

强制路径为相对路径。

如果给定绝对路径,则从其根组件中剥离。

示例

类 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"
链接到此函数

relative_to(path, cwd, opts \\ [])

查看源代码
@spec relative_to(t(), t(), keyword()) :: binary()

返回 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"
链接到此函数

relative_to_cwd(path, opts \\ [])

查看源代码
@spec relative_to_cwd(
  t(),
  keyword()
) :: binary()

方便获取相对于当前工作目录的路径。

如果由于某种原因无法检索当前工作目录,则此函数返回给定的 path

检查 relative_to/3 以了解支持的选项。

@spec rootname(t()) :: binary()

返回 path,去除 extension

示例

iex> Path.rootname("/foo/bar")
"/foo/bar"

iex> Path.rootname("/foo/bar.ex")
"/foo/bar"
链接到此函数

rootname(path, extension)

查看源代码
@spec rootname(t(), t()) :: binary()

返回 path,去除 extension

此函数应用于删除可能存在也可能不存在的特定扩展名。

示例

iex> Path.rootname("/foo/bar.erl", ".erl")
"/foo/bar"

iex> Path.rootname("/foo/bar.erl", ".ex")
"/foo/bar.erl"
链接到此函数

safe_relative(path, cwd \\ File.cwd!())

查看源代码 (自 1.14.0 起)
@spec safe_relative(t(), t()) :: {:ok, binary()} | :error

返回一个受保护免受目录遍历攻击的相对路径。

通过消除 ... 组件来清理给定的相对路径。

此函数检查在扩展这些组件后,路径是否仍然“安全”。如果以下两者之一为真,则路径被视为不安全

  • 路径不是相对路径,例如 "/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
链接到此函数

safe_relative_to(path, cwd)

查看源代码 (自 1.14.0 起)
此函数已弃用。使用 safe_relative/2 代替。
@spec safe_relative_to(t(), t()) :: {:ok, binary()} | :error

返回一个受保护免受目录遍历攻击的相对路径。

有关此 API 的非弃用版本,请参见 safe_relative/2

@spec split(t()) :: [binary()]

根据路径分隔符将路径拆分为列表。

如果给定空字符串,则返回空列表。

在 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
链接到此函数

wildcard(glob, opts \\ [])

查看源代码
@spec wildcard(
  t(),
  keyword()
) :: [binary()]

根据给定的 glob 表达式遍历路径,并返回匹配列表。

通配符看起来像普通的路径,除了以下“通配符字符”以特殊方式解释

  • ? - 匹配一个字符。

  • * - 匹配任意数量的字符,直到文件名结束、下一个点或下一个斜杠。

  • ** - 作为单个模式使用的两个相邻 * 将匹配所有文件以及零个或多个目录和子目录。

  • [char1,char2,...] - 匹配列表中的任意字符;用连字符分隔的两个字符将匹配一个字符范围。 不要在逗号前后添加空格,否则它将匹配包含空格字符本身的路径。

  • {item1,item2,...} - 匹配其中一个备选项。 不要在逗号前后添加空格,否则它将匹配包含空格字符本身的路径。

其他字符代表自身。 只有在相同位置具有完全相同字符的路径才会匹配。 请注意,匹配区分大小写:"a" 不会匹配 "A"

目录分隔符必须始终写为 /,即使在 Windows 上也是如此。 您可以在调用此函数之前调用 Path.expand/1 来规范化路径。

\\ 开头的字符将失去其特殊含义。 请注意,在字符串字面量中,\\ 必须写为 \\\\。 例如,"\\\\?*" 将匹配以 ?. 开头的任何文件名。

默认情况下,模式 *? 不会匹配以点 . 开头的文件。 请参阅下面“选项”部分中的 :match_dot 选项。

选项

  • :match_dot - (布尔值) 如果为 false,则特殊通配符 *? 不会匹配以点 (.) 开头的文件。 如果为 true,则以 . 开头的文件将不会被特殊对待。 默认值为 false

示例

假设您有一个名为 projects 的目录,其中包含三个 Elixir 项目:elixirex_docplug。 您可以找到每个项目 ebin 目录中的所有 .beam 文件,如下所示

Path.wildcard("projects/*/ebin/**/*.beam")

如果您想搜索 .beam.app 文件,您可以执行以下操作

Path.wildcard("projects/*/ebin/**/*.{beam,app}")