檢視原始碼 路徑 (Elixir v1.16.2)

此模組提供便利功能,用於處理或擷取檔案系統路徑。

此模組中的函式可以接收字元資料作為引數,且會始終傳回編碼為 UTF-8 的字串。字元資料是字串或字元和字串的清單,請參閱 IO.chardata/0。如果給定二進位檔,無論編碼為何,其編碼都會保留。

此模組中的大部分函式不會與檔案系統互動,但有少數函式需要互動(例如 wildcard/2expand/1)。

摘要

類型

t()

路徑。

函式

將給定的路徑轉換為絕對路徑。

relative_to 建立路徑至 path

傳回路徑的最後一個組成部分,或如果路徑不包含任何目錄分隔符號,則傳回路徑本身。

傳回 path 的最後一個組成部分,並移除 extension

傳回 path 的目錄組成部分。

將路徑轉換為絕對路徑,並展開任何 ... 組成部分,以及開頭的 ~

根據第二個引數作為路徑,展開路徑,並展開任何 ... 字元。

傳回 path 的最後一個組成部分的副檔名。

加入路徑清單。

加入兩個路徑。

強制路徑為相對路徑。

傳回從 path 相對於 cwd 的直接相對路徑。

取得相對於目前工作目錄的的路徑。

傳回移除 extensionpath

傳回移除 extensionpath

傳回一個不受目錄穿越攻擊影響的相對路徑。

傳回一個不受目錄穿越攻擊影響的相對路徑。

將路徑以路徑分隔符號分割成一個清單。

傳回路徑類型。

根據指定的 glob 表達式遍歷路徑,並傳回符合條件的清單。

類型

函式

@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_to 建立路徑至 path

如果 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"

此模組中的函式支援字元資料,因此提供清單時會將其視為單一實體

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()

傳回移除 extensionpath

範例

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

iex> Path.rootname("/foo/bar.ex")
"/foo/bar"
連結到此函式

rootname(path, extension)

檢視原始碼
@spec rootname(t(), t()) :: binary()

傳回移除 extensionpath

此函式應使用於移除特定副檔名,不論副檔名是否存在。

範例

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

傳回一個不受目錄穿越攻擊影響的相對路徑。

請參閱 safe_relative/2 以取得此 API 的非棄用版本。

@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}")