檢視原始碼 檔案 (Elixir v1.16.2)

此模組包含用於處理檔案的函式。

其中一些函式是低階的,允許使用者與檔案或 IO 裝置互動,例如 open/2copy/3 等。此模組也提供與檔名搭配使用的高階函式,且其命名基於 Unix 變體。例如,使用者可以使用 cp/3 複製檔案,並使用 rm_rf/1 遞迴移除檔案和目錄。

提供給此模組函式的路徑可以是相對於目前工作目錄 (由 File.cwd/0 傳回),或絕對路徑。殼層慣例 (例如 ~) 皆不會自動展開。若要使用 ~/Downloads 等路徑,可以使用 Path.expand/1Path.expand/2 將路徑展開為絕對路徑。

編碼

為了讀寫檔案,必須使用 IO 模組中的函式。預設情況下,檔案會以二進位模式開啟,這需要 IO.binread/2IO.binwrite/2 函式與檔案互動。開發人員可以在開啟檔案時傳遞 :utf8 作為選項,然後必須使用較慢的 IO.read/2IO.write/2 函式,因為它們負責進行適當的轉換並提供適當的資料保證。

請注意,在 Elixir 中以字元清單提供時,檔名總是視為 UTF-8。特別是,我們預期殼層和作業系統已設定為使用 UTF-8 編碼。二進位檔名被視為原始檔名,並原樣傳遞給作業系統。

API

此模組中的大多數函式會在成功時傳回 :ok{:ok, result},否則傳回 {:error, reason}。這些函式也有以 ! 結尾的變體,在成功時會傳回結果 (而非 {:ok, result} 元組),或在失敗時引發例外。例如

File.read("hello.txt")
#=> {:ok, "World"}

File.read("invalid.txt")
#=> {:error, :enoent}

File.read!("hello.txt")
#=> "World"

File.read!("invalid.txt")
#=> raises File.Error

一般來說,開發人員如果想要在檔案不存在時做出反應,應使用前者。後者應在開發人員預期軟體在無法讀取檔案時會失敗時使用(即它實際上是一個例外)。

程序和原始檔案

每次開啟檔案時,Elixir 會產生一個新的程序。寫入檔案等於傳送訊息給寫入檔案描述符的程序。

這表示檔案可以在節點之間傳遞,而訊息傳遞保證它們可以在網路中寫入同一個檔案。

但是,您可能不總是願意為這個抽象化付出代價。在這種情況下,可以在 :raw 模式中開啟檔案。在操作大型檔案或在緊密迴圈中使用檔案時,選項 :read_ahead:delayed_write 也很有用。

查看 :file.open/2 以取得有關這些選項和其他效能考量的更多資訊。

在檔案中尋找

您也可以使用 :file 模組中的任何函數與 Elixir 傳回的檔案進行互動。例如,要從檔案中的特定位置讀取,請使用 :file.pread/3

File.write!("example.txt", "Eats, Shoots & Leaves")
file = File.open!("example.txt")
:file.pread(file, 15, 6)
#=> {:ok, "Leaves"}

或者,如果您需要追蹤目前的位置,請使用 :file.position/2:file.read/2

:file.position(file, 6)
#=> {:ok, 6}
:file.read(file, 6)
#=> {:ok, "Shoots"}
:file.position(file, {:cur, -12})
#=> {:ok, 0}
:file.read(file, 4)
#=> {:ok, "Eats"}

摘要

函數

設定目前的工作目錄。

cd/1 相同,但如果失敗,會引發 File.Error 例外。

將目前目錄變更為指定的 path,執行指定的函數,然後無論是否有例外,都回復到前一個路徑。

變更指定 file 的群組,群組由群組 ID gid 指定。成功時傳回 :ok,失敗時傳回 {:error, reason}

chgrp/2 相同,但如果失敗會引發 File.Error 例外。否則 :ok

變更給定 filemode

chmod/2 相同,但如果失敗會引發 File.Error 例外。否則 :ok

變更給定 file 的擁有者,由使用者 ID uid 給定。如果成功,傳回 :ok,否則傳回 {:error, reason}

chown/2 相同,但如果失敗會引發 File.Error 例外。否則 :ok

關閉 io_device 參考的檔案。它通常會傳回 :ok,但有些嚴重錯誤(例如記憶體不足)除外。

source 的內容複製到 destination

copy/3 相同,但如果失敗會引發 File.CopyError 例外。否則傳回 bytes_copied

source_file 的內容複製到 destination_file,並保留其模式。

cp/3 相同,但如果失敗會引發 File.CopyError 例外。否則傳回 :ok

source 中的內容遞迴複製到 destination,並維護來源目錄結構和模式。

cp_r/3 相同,但如果失敗會引發 File.CopyError 例外。否則傳回已複製檔案的清單。

取得目前的作業目錄。

cwd/0 相同,但如果失敗,會引發 File.Error 例外。

如果給定的路徑是目錄,則傳回 true

如果給定的路徑存在,則傳回 true

為檔案 existing

建立硬連結 new

ln/2 相同,但如果失敗,會引發 File.LinkError 例外。否則傳回 :ok

為檔案或目錄 existing

建立符號連結 new

ln_s/2 相同,但如果失敗,會引發 File.LinkError 例外。否則傳回 :ok

傳回給定目錄中的檔案清單。

ls/1 相同,但如果發生錯誤,會引發 File.Error 例外。

傳回 path

的資訊。如果檔案是符號連結,則將 type

設定為 :symlink

,並傳回連結的 File.Stat 結構。對於任何其他檔案,傳回與 stat/2 完全相同的數值。

lstat/2 相同,但直接傳回 File.Stat 結構,或者如果傳回錯誤,則引發 File.Error 例外。

嘗試建立目錄 path

mkdir/1 相同,但如果失敗,會引發 File.Error 例外。否則為 :ok

嘗試建立目錄 path

mkdir_p/1 相同,但如果失敗,會引發 File.Error 例外。否則為 :ok

開啟給定的 path

類似於 open/2,但預期最後一個引數為函式。

類似於 open/2,但如果檔案無法開啟,會引發 File.Error 例外。否則傳回 IO 裝置。

類似於 open/3,但如果檔案無法開啟,會引發 File.Error 例外。

傳回 {:ok, binary},其中 binary 是包含 path 內容的二進制資料物件,或如果發生錯誤,傳回 {:error, reason}

傳回包含指定檔案名稱內容的二進制資料,或如果發生錯誤,引發 File.Error 例外。

讀取 path 的符號連結。

read_link/1 相同,但直接傳回目標,或如果傳回錯誤,引發 File.Error 例外。

如果路徑是常規檔案,傳回 true

source 檔案重新命名為 destination 檔案。它可用於在目錄之間移動檔案(和目錄)。如果移動檔案,您必須完全指定 destination 檔案名稱,僅指定其目錄是不夠的。

rename/2 相同,但如果失敗,會引發 File.RenameError 例外。否則傳回 :ok

嘗試刪除檔案 path

rm/1 相同,但在失敗時會引發 File.Error 例外。否則為 :ok

在指定的 path 遞迴移除檔案和目錄。符號連結不會被追蹤,而是直接移除,不存在的檔案會直接忽略(即不會導致此函式失敗)。

rm_rf/1 相同,但在失敗時會引發 File.Error 例外,否則會傳回已移除檔案或目錄的清單。

嘗試刪除 path 的目錄。

rmdir/1 相同,但如果失敗,會引發 File.Error 例外。否則為 :ok

傳回有關 path 的資訊。如果存在,會傳回 {:ok, info} 元組,其中 info 是 File.Stat 結構。如果發生失敗,會傳回 {:error, reason},原因與 read/1 相同。

stat/2 相同,但會直接傳回 File.Stat,或是在傳回錯誤時引發 File.Error 例外。

傳回給定 pathFile.Stream,並具有給定的 modes

更新給定檔案的修改時間 (mtime) 和存取時間 (atime)。

touch/2 相同,但如果失敗,會引發 File.Error 例外。否則傳回 :ok

content 寫入檔案 path

write/3 相同,但如果失敗,會引發 File.Error 例外。否則傳回 :ok

將給定的 File.Stat 寫回給定路徑的檔案系統。傳回 :ok{:error, reason}

write_stat/3 相同,但如果失敗,會引發 File.Error 例外。否則傳回 :ok

類型

@type encoding_mode() ::
  :utf8
  | {:encoding,
     :latin1
     | :unicode
     | :utf8
     | :utf16
     | :utf32
     | {:utf16, :big | :little}
     | {:utf32, :big | :little}}
@type erlang_time() ::
  {{year :: non_neg_integer(), month :: 1..12, day :: 1..31},
   {hour :: 0..23, minute :: 0..59, second :: 0..59}}
@type io_device() :: :file.io_device()
@type mode() ::
  :append
  | :binary
  | :charlist
  | :compressed
  | :delayed_write
  | :exclusive
  | :raw
  | :read
  | :read_ahead
  | :sync
  | :write
  | {:read_ahead, pos_integer()}
  | {:delayed_write, non_neg_integer(), non_neg_integer()}
  | encoding_mode()
@type on_conflict_callback() :: (Path.t(), Path.t() -> boolean())
@type posix() :: :file.posix()
@type posix_time() :: integer()
@type read_offset_mode() :: {:read_offset, non_neg_integer()}
@type stat_options() :: [{:time, :local | :universal | :posix}]
@type stream_mode() ::
  encoding_mode()
  | read_offset_mode()
  | :append
  | :compressed
  | :delayed_write
  | :trim_bom
  | {:read_ahead, pos_integer() | false}
  | {:delayed_write, non_neg_integer(), non_neg_integer()}

函數

@spec cd(Path.t()) :: :ok | {:error, posix()}

設定目前的工作目錄。

BEAM 全域設定目前工作目錄。如果多個程序同時變更目前工作目錄,可能會導致競爭條件。若要在特定目錄中執行外部命令,而不會變更全域目前工作目錄,請使用 System.cmd/3Port.open/2:cd 選項。

如果成功,則傳回 :ok,否則傳回 {:error, reason}

@spec cd!(Path.t()) :: :ok

cd/1 相同,但如果失敗,會引發 File.Error 例外。

@spec cd!(Path.t(), (-> res)) :: res when res: var

將目前目錄變更為指定的 path,執行指定的函數,然後無論是否有例外,都回復到前一個路徑。

BEAM 全域暫時設定目前工作目錄。如果多個程序同時變更目前工作目錄,可能會導致競爭條件。若要在特定目錄中執行外部命令,而不會變更全域目前工作目錄,請使用 System.cmd/3Port.open/2:cd 選項。

如果擷取或變更目前目錄失敗,則會引發錯誤。

@spec chgrp(Path.t(), non_neg_integer()) :: :ok | {:error, posix()}

變更指定 file 的群組,群組由群組 ID gid 指定。成功時傳回 :ok,失敗時傳回 {:error, reason}

@spec chgrp!(Path.t(), non_neg_integer()) :: :ok

chgrp/2 相同,但如果失敗會引發 File.Error 例外。否則 :ok

@spec chmod(Path.t(), non_neg_integer()) :: :ok | {:error, posix()}

變更給定 filemode

如果成功,則傳回 :ok,否則傳回 {:error, reason}

權限

檔案權限透過將下列八進位模式加總來指定

  • 0o400 - 讀取權限:擁有者

  • 0o200 - 寫入權限:擁有者

  • 0o100 - 執行權限:擁有者

  • 0o040 - 讀取權限:群組

  • 0o020 - 寫入權限:群組

  • 0o010 - 執行權限:群組

  • 0o004 - 讀取權限:其他

  • 0o002 - 寫入權限:其他

  • 0o001 - 執行權限:其他

例如,設定模式 0o755 會給予擁有者寫入、讀取和執行權限,並給予群組和其他人讀取和執行權限。

@spec chmod!(Path.t(), non_neg_integer()) :: :ok

chmod/2 相同,但如果失敗會引發 File.Error 例外。否則 :ok

@spec chown(Path.t(), non_neg_integer()) :: :ok | {:error, posix()}

變更給定 file 的擁有者,由使用者 ID uid 給定。如果成功,傳回 :ok,否則傳回 {:error, reason}

@spec chown!(Path.t(), non_neg_integer()) :: :ok

chown/2 相同,但如果失敗會引發 File.Error 例外。否則 :ok

@spec close(io_device()) :: :ok | {:error, posix() | :badarg | :terminated}

關閉 io_device 參考的檔案。它通常會傳回 :ok,但有些嚴重錯誤(例如記憶體不足)除外。

請注意,如果在開啟檔案時使用了 :delayed_write 選項,close/1 可能會傳回舊的寫入錯誤,甚至不會嘗試關閉檔案。請參閱 open/2 以取得更多資訊。

連結至這個函數

copy(source, destination, bytes_count \\ :infinity)

檢視來源
@spec copy(Path.t() | io_device(), Path.t() | io_device(), pos_integer() | :infinity) ::
  {:ok, non_neg_integer()} | {:error, posix()}

source 的內容複製到 destination

兩個參數都可以是檔案名稱或使用 open/2 開啟的 IO 裝置。bytes_count 指定要複製的位元組數,預設為 :infinity

如果檔案 destination 已存在,它會被 source 中的內容覆寫。

如果成功,則傳回 {:ok, bytes_copied},否則傳回 {:error, reason}

cp/3 相比,此函式層級較低,允許從裝置複製到裝置,並受限於位元組數。另一方面,cp/3 會對來源和目的地執行更廣泛的檢查,且在複製後也會保留檔案模式。

典型的錯誤原因與 open/2read/1write/3 中相同。

連結至這個函數

copy!(source, destination, bytes_count \\ :infinity)

檢視來源
@spec copy!(Path.t() | io_device(), Path.t() | io_device(), pos_integer() | :infinity) ::
  non_neg_integer()

copy/3 相同,但如果失敗會引發 File.CopyError 例外。否則傳回 bytes_copied

連結至這個函數

cp(source_file, destination_file, options \\ [])

檢視來源
@spec cp(Path.t(), Path.t(), [{:on_conflict, on_conflict_callback()}]) ::
  :ok | {:error, posix()}

source_file 的內容複製到 destination_file,並保留其模式。

source_file 必須是檔案或指向檔案的符號連結。destination_file 必須是非現有檔案的路徑。如果任一為目錄,則會傳回 {:error, :eisdir}

此函式在成功時傳回 :ok。否則,傳回 {:error, reason}

如果您想從一個 IO 裝置複製內容到另一個裝置,或從來源直接複製到目的地而不保留模式,請改為查看 copy/3

注意:類 Unix 系統中的 cp 指令會根據目的地是否為現有目錄而有不同的行為。我們選擇明確禁止複製到目的地目錄,且如果嘗試這麼做會傳回錯誤。

選項

  • :on_conflict - (自 v1.14.0 起) 在目的地中已存在檔案時呼叫。此函式接收 source_filedestination_file 的引數。如果應覆寫現有檔案,則應傳回 true;否則傳回 false。預設的回呼傳回 true。在較早的版本中,此回呼可以作為第三個引數提供,但此行為現已不建議使用。
連結至這個函數

cp!(source_file, destination_file, options \\ [])

檢視來源
@spec cp!(Path.t(), Path.t(), [{:on_conflict, on_conflict_callback()}]) :: :ok

cp/3 相同,但如果失敗會引發 File.CopyError 例外。否則傳回 :ok

連結至這個函數

cp_r(source, destination, options \\ [])

檢視來源
@spec cp_r(Path.t(), Path.t(),
  on_conflict: on_conflict_callback(),
  dereference_symlinks: boolean()
) ::
  {:ok, [binary()]} | {:error, posix(), binary()}

source 中的內容遞迴複製到 destination,並維護來源目錄結構和模式。

如果 source 是檔案或指向檔案的符號連結,則 destination 必須是現有檔案的路徑、指向檔案的符號連結或非現有檔案的路徑。

如果 source 是目錄或指向目錄的符號連結,則 destination 必須是現有的 directory 或指向目錄的符號連結,或非現有目錄的路徑。

如果來源是一個檔案,它會複製 sourcedestination。如果 source 是目錄,它會複製來源目錄內的內容到 destination 目錄。

如果目的地中已存在檔案,它會呼叫以選項提供的 on_conflict 回呼函式。更多資訊請參閱「選項」。

這個函式在複製檔案時可能會失敗,在這種情況下,它會讓目的地目錄處於不乾淨的狀態,其中已複製的檔案不會被移除。

如果成功,函式會傳回 {:ok, files_and_directories}files_and_directories 會列出所有已複製的檔案和目錄,順序不特定。否則,它會傳回 {:error, reason, file}

注意:類 Unix 系統中的 cp 指令會根據 destination 是否為現有目錄而有不同的行為。我們選擇明確禁止這種行為。如果 sourcefiledestination 是目錄,將會傳回 {:error, :eisdir}

選項

  • :on_conflict - (自 v1.14.0 起) 在目的地中已存在檔案時呼叫。函式會接收 sourcedestination 的引數。如果現有檔案應該被覆寫,它應該傳回 true;否則傳回 false。預設的回呼函式傳回 true。在較早的版本中,這個回呼函式可以作為第三個引數提供,但這種行為現在已不建議使用。

  • :dereference_symlinks - (自 v1.14.0 起) 預設情況下,這個函式會透過建立指向相同位置的符號連結來複製符號連結。如果將此選項設定為 true,它會強制符號連結被取消引用,並複製其內容。如果取消引用的檔案不存在,則操作會失敗。預設值為 false

範例

# Copies file "a.txt" to "b.txt"
File.cp_r("a.txt", "b.txt")

# Copies all files in "samples" to "tmp"
File.cp_r("samples", "tmp")

# Same as before, but asks the user how to proceed in case of conflicts
File.cp_r("samples", "tmp", on_conflict: fn source, destination ->
  IO.gets("Overwriting #{destination} by #{source}. Type y to confirm. ") == "y\n"
end)
連結至這個函數

cp_r!(source, destination, options \\ [])

檢視來源
@spec cp_r!(Path.t(), Path.t(),
  on_conflict: on_conflict_callback(),
  dereference_symlinks: boolean()
) ::
  [binary()]

cp_r/3 相同,但如果失敗會引發 File.CopyError 例外。否則傳回已複製檔案的清單。

@spec cwd() :: {:ok, binary()} | {:error, posix()}

取得目前的作業目錄。

在罕見的情況下,這個函式可能會在類 Unix 系統上失敗。如果目前目錄的父目錄沒有讀取權限,可能會發生這種情況。因此,如果成功,它會傳回 {:ok, cwd};否則傳回 {:error, reason}

@spec cwd!() :: binary()

cwd/0 相同,但如果失敗,會引發 File.Error 例外。

@spec dir?(Path.t(), [dir_option]) :: boolean() when dir_option: :raw

如果給定的路徑是目錄,則傳回 true

這個函式會追蹤符號連結,因此如果符號連結指向目錄,它會傳回 true

選項

支援的選項為

  • :raw - 單一原子,用於繞過檔案伺服器,只在本地端檢查檔案

範例

File.dir?("./test")
#=> true

File.dir?("test")
#=> true

File.dir?("/usr/bin")
#=> true

File.dir?("~/Downloads")
#=> false

"~/Downloads" |> Path.expand() |> File.dir?()
#=> true
連結至這個函數

exists?(path, opts \\ [])

檢視來源
@spec exists?(Path.t(), [exists_option]) :: boolean() when exists_option: :raw

如果給定的路徑存在,則傳回 true

它可以是常規檔案、目錄、socket、符號連結、命名管線或裝置檔案。對於指向不存在目標的符號連結,會傳回 false

選項

支援的選項為

  • :raw - 單一原子,用於繞過檔案伺服器,只在本地端檢查檔案

範例

File.exists?("test/")
#=> true

File.exists?("missing.txt")
#=> false

File.exists?("/dev/null")
#=> true
連結至這個函數

ln(existing, new)

檢視原始碼 (自 1.5.0 起)
@spec ln(Path.t(), Path.t()) :: :ok | {:error, posix()}

為檔案 existing

建立硬連結 new

如果成功,會傳回 :ok;否則會傳回 {:error, reason}。如果作業系統不支援硬連結,會傳回 {:error, :enotsup}

連結至這個函數

ln!(existing, new)

檢視原始碼 (自 1.5.0 起)
@spec ln!(Path.t(), Path.t()) :: :ok

ln/2 相同,但如果失敗,會引發 File.LinkError 例外。否則傳回 :ok

連結至這個函數

ln_s(existing, new)

檢視原始碼 (自 1.5.0 起)
@spec ln_s(Path.t(), Path.t()) :: :ok | {:error, posix()}

為檔案或目錄 existing

建立符號連結 new

如果成功,會傳回 :ok;否則會傳回 {:error, reason}。如果作業系統不支援符號連結,會傳回 {:error, :enotsup}

@spec ln_s!(Path.t(), Path.t()) :: :ok

ln_s/2 相同,但如果失敗,會引發 File.LinkError 例外。否則傳回 :ok

@spec ls(Path.t()) :: {:ok, [binary()]} | {:error, posix()}

傳回給定目錄中的檔案清單。

不忽略隱藏檔案,且結果不會排序。

由於檔案系統將目錄視為檔案,因此目錄也會包含在傳回值中。

如果成功,會傳回 {:ok, files};否則會傳回 {:error, reason}

@spec ls!(Path.t()) :: [binary()]

ls/1 相同,但如果發生錯誤,會引發 File.Error 例外。

@spec lstat(Path.t(), stat_options()) :: {:ok, File.Stat.t()} | {:error, posix()}

傳回 path

的資訊。如果檔案是符號連結,則將 type

設定為 :symlink

,並傳回連結的 File.Stat 結構。對於任何其他檔案,傳回與 stat/2 完全相同的數值。

如需更多詳細資訊,請參閱 :file.read_link_info/2

選項

可接受的選項為

  • :time - 設定如何傳回檔案時間戳記

:time 的值可以是

  • :universal - 傳回 UTC 中的 {date, time} 組合 (預設)
  • :local - 使用機器時間傳回 {date, time} 組合
  • :posix - 以自紀元以來的整數秒傳回時間

注意:由於大多數作業系統會以 POSIX 時間格式儲存檔案時間,因此使用 time: :posix 選項擷取檔案資訊會比較快。

@spec lstat!(Path.t(), stat_options()) :: File.Stat.t()

lstat/2 相同,但直接傳回 File.Stat 結構,或者如果傳回錯誤,則引發 File.Error 例外。

@spec mkdir(Path.t()) :: :ok | {:error, posix()}

嘗試建立目錄 path

不會建立遺失的父目錄。如果成功,則傳回 :ok,如果發生錯誤,則傳回 {:error, reason}

典型的錯誤原因是

  • :eacces - 遺失 path 父目錄的搜尋或寫入權限
  • :eexist - 已經有檔案或目錄命名為 path
  • :enoent - path 的組成元件不存在
  • :enospc - 裝置上沒有剩餘空間
  • :enotdir - path 的組成元件不是目錄;在某些平台上,會傳回 :enoent
@spec mkdir!(Path.t()) :: :ok

mkdir/1 相同,但如果失敗,會引發 File.Error 例外。否則為 :ok

@spec mkdir_p(Path.t()) :: :ok | {:error, posix()}

嘗試建立目錄 path

會建立遺失的父目錄。如果成功,則傳回 :ok,如果發生錯誤,則傳回 {:error, reason}

典型的錯誤原因是

  • :eacces - 遺失 path 父目錄的搜尋或寫入權限
  • :enospc - 裝置上沒有剩餘空間
  • :enotdir - path 的組成元件不是目錄
@spec mkdir_p!(Path.t()) :: :ok

mkdir_p/1 相同,但如果失敗,會引發 File.Error 例外。否則為 :ok

連結至這個函數

open(path, modes_or_function \\ [])

檢視來源
@spec open(Path.t(), [mode() | :ram]) :: {:ok, io_device()} | {:error, posix()}
@spec open(Path.t(), (io_device() -> res)) :: {:ok, res} | {:error, posix()}
when res: var

開啟給定的 path

為了寫入和讀取檔案,必須使用 IO 模組中的函式。預設情況下,檔案會以 :binary 模式開啟,這需要函式 IO.binread/2IO.binwrite/2 與檔案互動。開發人員可以在開啟檔案時傳遞 :utf8 作為選項,然後 IO 中的所有其他函式都會可用,因為它們會直接使用 Unicode 資料。

modes_or_function 可以是模式清單或函式。如果它是清單,則會視為模式清單(如下所述)。如果它是函式,則等於呼叫 open(path, [], modes_or_function)。請參閱 open/3 的文件以取得關於此函式的更多資訊。

允許的模式

  • :binary - 以二進位模式開啟檔案,停用 Unicode 順序的特殊處理(預設模式)。

  • :read - 必須存在的檔案會開啟以進行讀取。

  • :write - 檔案會開啟以進行寫入。如果檔案不存在,則會建立檔案。

    如果檔案存在,而且寫入未與讀取結合,則會截斷檔案。

  • :append - 檔案將開啟為寫入模式,如果檔案不存在則會建立。對以附加模式開啟的檔案的每次寫入操作都將在檔案結尾進行。

  • :exclusive - 開啟寫入模式時,如果檔案不存在則會建立。如果檔案存在,開啟將傳回 {:error, :eexist}

  • :charlist - 給定此參數時,檔案的讀取操作將傳回字元清單,而非二進位資料。

  • :compressed - 使得可以讀取或寫入 gzip 壓縮檔案。

    壓縮選項必須與讀取或寫入結合使用,但不能同時使用。請注意,使用 stat/1 取得的檔案大小很可能與可以從壓縮檔案讀取的位元組數不符。

  • :utf8 - 此選項表示資料實際儲存在磁碟檔案中的方式,並使檔案自動將字元轉換為 UTF-8 和從 UTF-8 轉換。

    如果傳送至檔案的資料無法轉換為 UTF-8,或如果資料是由傳回無法處理資料字元範圍的格式的資料的函式所讀取,則會發生錯誤,且檔案將關閉。

  • :delayed_write, :raw, :ram, :read_ahead, :sync, {:encoding, ...}, {:read_ahead, pos_integer}, {:delayed_write, non_neg_integer, non_neg_integer} - 有關這些選項的詳細資訊,請參閱 :file.open/2

此函式傳回

  • {:ok, io_device} - 檔案已在請求的模式中開啟。

    io_device 實際上是處理檔案的程序的 PID。此程序會監控最初開啟檔案的程序(擁有者程序)。如果擁有者程序終止,則檔案將關閉,且程序本身也會終止。如果連結至 io_device 的任何程序終止,則檔案將關閉,且程序本身將終止。

    從此呼叫傳回的 io_device 可用作 IO 模組函式的引數。

  • {:error, reason} - 檔案無法開啟。

範例

{:ok, file} = File.open("foo.tar.gz", [:read, :compressed])
IO.read(file, :line)
File.close(file)
連結至這個函數

open(path, modes, function)

檢視來源
@spec open(Path.t(), [mode() | :ram], (io_device() -> res)) ::
  {:ok, res} | {:error, posix()}
when res: var

類似於 open/2,但預期最後一個引數為函式。

檔案開啟後,作為引數傳遞給函式,並在函式傳回後自動關閉,不論在執行函式時是否發生錯誤。

傳回 {:ok, function_result} 表示成功,否則傳回 {:error, reason}

此函式預期檔案會成功關閉,通常情況下會如此,除非有提供 :delayed_write 選項。因此,我們不建議將 :delayed_write 傳遞給此函式。

範例

File.open("file.txt", [:read, :write], fn file ->
  IO.read(file, :line)
end)

請參閱 open/2 以取得可用 modes 清單。

連結至這個函數

open!(path, modes_or_function \\ [])

檢視來源
@spec open!(Path.t(), [mode() | :ram]) :: io_device()
@spec open!(Path.t(), (io_device() -> res)) :: res when res: var

類似於 open/2,但如果檔案無法開啟,會引發 File.Error 例外。否則傳回 IO 裝置。

請參閱 open/2 以取得可用模式清單。

連結至這個函數

open!(path, modes, function)

檢視來源
@spec open!(Path.t(), [mode() | :ram], (io_device() -> res)) :: res when res: var

類似於 open/3,但如果檔案無法開啟,會引發 File.Error 例外。

如果成功開啟檔案,它會在 IO 裝置上傳回 function 結果。

請參閱 open/2 以取得可用 modes 清單。

@spec read(Path.t()) :: {:ok, binary()} | {:error, posix()}

傳回 {:ok, binary},其中 binary 是包含 path 內容的二進制資料物件,或如果發生錯誤,傳回 {:error, reason}

常見錯誤原因

  • :enoent - 檔案不存在
  • :eacces - 沒有讀取檔案或搜尋其中一個父目錄的權限
  • :eisdir - 指定的檔案是目錄
  • :enotdir - 檔案名稱的組成部分不是目錄;在某些平台上,會傳回 :enoent
  • :enomem - 沒有足夠的記憶體儲存檔案內容

您可以使用 :file.format_error/1 取得錯誤的描述字串。

@spec read!(Path.t()) :: binary()

傳回包含指定檔案名稱內容的二進制資料,或如果發生錯誤,引發 File.Error 例外。

連結至這個函數

read_link(path)

檢視原始碼 (自 1.5.0 起)
@spec read_link(Path.t()) :: {:ok, binary()} | {:error, posix()}

讀取 path 的符號連結。

如果 path 存在且為符號連結,傳回 {:ok, target},否則傳回 {:error, reason}

更多詳細資訊,請參閱 :file.read_link/1

典型的錯誤原因是

  • :einval - 路徑不是符號連結
  • :enoent - 路徑不存在
  • :enotsup - 目前平台不支援符號連結
連結至這個函數

read_link!(path)

檢視原始碼 (自 1.5.0 起)
@spec read_link!(Path.t()) :: binary()

read_link/1 相同,但直接傳回目標,或如果傳回錯誤,引發 File.Error 例外。

連結至這個函數

regular?(path, opts \\ [])

檢視來源
@spec regular?(Path.t(), [regular_option]) :: boolean() when regular_option: :raw

如果路徑是常規檔案,傳回 true

此函式會追蹤符號連結,因此如果符號連結指向一般檔案,會傳回 true

選項

支援的選項為

  • :raw - 單一原子,用於繞過檔案伺服器,只在本地端檢查檔案

範例

File.regular?(__ENV__.file)
#=> true
連結至這個函數

rename(source, destination)

檢視原始碼 (自 1.1.0 起)
@spec rename(Path.t(), Path.t()) :: :ok | {:error, posix()}

source 檔案重新命名為 destination 檔案。它可用於在目錄之間移動檔案(和目錄)。如果移動檔案,您必須完全指定 destination 檔案名稱,僅指定其目錄是不夠的。

如果成功,傳回 :ok,否則傳回 {:error, reason}

注意:類 Unix 系統中的 mv 指令會根據 source 是否為檔案,以及 destination 是否為現有目錄而有不同的行為。我們選擇明確禁止這種行為。

範例

# Rename file "a.txt" to "b.txt"
File.rename("a.txt", "b.txt")

# Rename directory "samples" to "tmp"
File.rename("samples", "tmp")
連結至這個函數

rename!(source, destination)

檢視原始碼 (自 1.9.0 起)
@spec rename!(Path.t(), Path.t()) :: :ok

rename/2 相同,但如果失敗,會引發 File.RenameError 例外。否則傳回 :ok

@spec rm(Path.t()) :: :ok | {:error, posix()}

嘗試刪除檔案 path

如果成功,傳回 :ok,如果發生錯誤,傳回 {:error, reason}

請注意,即使在唯讀模式下,檔案也會被刪除。

典型的錯誤原因是

  • :enoent - 檔案不存在
  • :eacces - 缺少檔案或其父項目的權限
  • :eperm - 檔案是目錄,而使用者不是超級使用者
  • :enotdir - 檔案名稱的組成部分不是目錄;在某些平台上,會傳回 :enoent
  • :einval - 檔案名稱的類型不正確,例如元組

範例

File.rm("file.txt")
#=> :ok

File.rm("tmp_dir/")
#=> {:error, :eperm}
@spec rm!(Path.t()) :: :ok

rm/1 相同,但在失敗時會引發 File.Error 例外。否則為 :ok

@spec rm_rf(Path.t()) :: {:ok, [binary()]} | {:error, posix(), binary()}

在指定的 path 遞迴移除檔案和目錄。符號連結不會被追蹤,而是直接移除,不存在的檔案會直接忽略(即不會導致此函式失敗)。

傳回 {:ok, files_and_directories},其中包含以特定順序移除的所有檔案和目錄,否則傳回 {:error, reason, file}

範例

File.rm_rf("samples")
#=> {:ok, ["samples", "samples/1.txt"]}

File.rm_rf("unknown")
#=> {:ok, []}
@spec rm_rf!(Path.t()) :: [binary()]

rm_rf/1 相同,但在失敗時會引發 File.Error 例外,否則會傳回已移除檔案或目錄的清單。

@spec rmdir(Path.t()) :: :ok | {:error, posix()}

嘗試刪除 path 的目錄。

如果成功,傳回 :ok,如果發生錯誤,傳回 {:error, reason}。如果目錄不為空,則傳回 {:error, :eexist}

範例

File.rmdir("tmp_dir")
#=> :ok

File.rmdir("non_empty_dir")
#=> {:error, :eexist}

File.rmdir("file.txt")
#=> {:error, :enotdir}
@spec rmdir!(Path.t()) :: :ok | {:error, posix()}

rmdir/1 相同,但如果失敗,會引發 File.Error 例外。否則為 :ok

@spec stat(Path.t(), stat_options()) :: {:ok, File.Stat.t()} | {:error, posix()}

傳回有關 path 的資訊。如果存在,會傳回 {:ok, info} 元組,其中 info 是 File.Stat 結構。如果發生失敗,會傳回 {:error, reason},原因與 read/1 相同。

選項

可接受的選項為

  • :time - 設定如何傳回檔案時間戳記

:time 的值可以是

  • :universal - 傳回 UTC 中的 {date, time} 組合 (預設)
  • :local - 使用與機器相同的時區傳回 {date, time} 元組
  • :posix - 以自紀元以來的整數秒傳回時間

注意:由於大多數作業系統會以 POSIX 時間格式儲存檔案時間,因此使用 time: :posix 選項擷取檔案資訊會比較快。

@spec stat!(Path.t(), stat_options()) :: File.Stat.t()

stat/2 相同,但會直接傳回 File.Stat,或是在傳回錯誤時引發 File.Error 例外。

連結至這個函數

stream!(path, line_or_bytes_modes \\ [])

檢視來源
@spec stream!(Path.t(), :line | pos_integer() | [stream_mode()]) :: File.Stream.t()

File.stream!/3 的捷徑。

連結至這個函數

stream!(path, line_or_bytes, modes)

檢視來源
@spec stream!(Path.t(), :line | pos_integer(), [stream_mode()]) :: File.Stream.t()

傳回給定 pathFile.Stream,並具有給定的 modes

串流同時實作 EnumerableCollectable 協定,這表示它可用於讀取和寫入。

line_or_bytes 參數透過 :line (預設) 或給定的位元組數,設定串流時檔案的讀取方式。使用 :line 選項時,CRLF 換行符 ("\r\n") 會正規化為 LF ("\n")。

類似於其他檔案操作,串流可以在一個節點中建立並轉發到另一個節點。一旦串流在另一個節點中開啟,要求就會被傳送給建立者節點,以產生檔案串流的程序。

操作串流可能會在開啟時失敗,原因與 File.open!/2 相同。請注意,每次串流開始時,檔案都會自動開啟。無需傳遞 :read:write 模式,因為這些模式會由 Elixir 自動設定。

原始檔案

由於 Elixir 控制串流檔案開啟的時間,因此無法共用基礎裝置,因此出於效能考量,以原始模式開啟檔案很方便。因此,如果串流在與建立串流的節點中開啟,且未指定編碼,Elixir :raw 模式開啟串流,並使用 :read_ahead 選項。這表示串流到檔案中的任何資料都必須轉換為 iodata/0 類型。例如,如果你在模式參數中傳遞 [encoding: :utf8][encoding: {:utf16, :little}],基礎串流將使用 IO.write/2String.Chars 協定來轉換資料。請參閱 IO.binwrite/2IO.write/2

如果串流要在緊密迴圈中寫入,你也可以考慮傳遞 :delayed_write 選項。

位元組順序標記和讀取偏移量

如果你在模式參數中傳遞 :trim_bom,串流會在從檔案讀取時修剪 UTF-8、UTF-16 和 UTF-32 位元組順序標記。

請注意,此函式不會嘗試根據 BOM 找出檔案編碼。從 Elixir v1.16.0 開始,你也可以傳遞 :read_offset,在列舉串流時會略過該偏移量(如果同時給定 :read_offset:trim_bom,則會在 BOM 之後略過偏移量)。

範例

# Read a utf8 text file which may include BOM
File.stream!("./test/test.txt", [:trim_bom, encoding: :utf8])

# Read in 2048 byte chunks rather than lines
File.stream!("./test/test.data", 2048)

請參閱 Stream.run/1,以取得串流到檔案的範例。

連結至這個函數

touch(path, time \\ System.os_time(:second))

檢視來源
@spec touch(Path.t(), erlang_time() | posix_time()) :: :ok | {:error, posix()}

更新給定檔案的修改時間 (mtime) 和存取時間 (atime)。

如果檔案不存在,則會建立檔案。需要以 UTC 格式提供日期時間 (由 :erlang.universaltime() 傳回),或提供表示 POSIX 時間戳記的整數 (由 System.os_time(:second) 傳回)。

在類 Unix 系統中,變更修改時間可能需要您成為 root 或檔案的所有者。擁有寫入權限可能還不夠。在這些情況下,第一次觸及檔案 (建立檔案) 會成功,但觸及現有檔案會失敗,並傳回 {:error, :eperm}

範例

File.touch("/tmp/a.txt", {{2018, 1, 30}, {13, 59, 59}})
#=> :ok
File.touch("/fakedir/b.txt", {{2018, 1, 30}, {13, 59, 59}})
{:error, :enoent}

File.touch("/tmp/a.txt", 1544519753)
#=> :ok
連結至這個函數

touch!(path, time \\ System.os_time(:second))

檢視來源
@spec touch!(Path.t(), erlang_time() | posix_time()) :: :ok

touch/2 相同,但如果失敗,會引發 File.Error 例外。否則傳回 :ok

如果檔案不存在,則會建立檔案。需要以 UTC 格式提供日期時間 (由 :erlang.universaltime() 傳回),或提供表示 POSIX 時間戳記的整數 (由 System.os_time(:second) 傳回)。

範例

File.touch!("/tmp/a.txt", {{2018, 1, 30}, {13, 59, 59}})
#=> :ok
File.touch!("/fakedir/b.txt", {{2018, 1, 30}, {13, 59, 59}})
** (File.Error) could not touch "/fakedir/b.txt": no such file or directory

File.touch!("/tmp/a.txt", 1544519753)
連結至這個函數

write(path, content, modes \\ [])

檢視來源
@spec write(Path.t(), iodata(), [mode()]) :: :ok | {:error, posix()}

content 寫入檔案 path

如果檔案不存在,則會建立檔案。如果檔案存在,則會覆寫先前的內容。如果成功,則傳回 :ok,如果發生錯誤,則傳回 {:error, reason}

content 必須是 iodata (位元組清單或二進位)。設定此函式的編碼並無作用。

警告:每次呼叫此函式時,都會開啟一個檔案描述子,並產生一個新的程序來寫入檔案。因此,如果您在迴圈中執行多次寫入,透過 File.open/2 開啟檔案,並使用 IO 中的函式寫入檔案,將會比多次呼叫此函式產生更好的效能。

典型的錯誤原因是

  • :enoent - 檔案名稱的組成部分不存在
  • :enotdir - 檔案名稱的組成部分不是目錄;在某些平台上,會傳回 :enoent
  • :enospc - 裝置上沒有剩餘空間
  • :eacces - 沒有寫入檔案或搜尋其中一個父目錄的權限
  • :eisdir - 指定的檔案是目錄

請查看 File.open/2,以取得其他可用選項。

連結至這個函數

write!(path, content, modes \\ [])

檢視來源
@spec write!(Path.t(), iodata(), [mode()]) :: :ok

write/3 相同,但如果失敗,會引發 File.Error 例外。否則傳回 :ok

連結至這個函數

write_stat(path, stat, opts \\ [])

檢視來源
@spec write_stat(Path.t(), File.Stat.t(), stat_options()) :: :ok | {:error, posix()}

將給定的 File.Stat 寫回給定路徑的檔案系統。傳回 :ok{:error, reason}

連結至這個函數

write_stat!(path, stat, opts \\ [])

檢視來源
@spec write_stat!(Path.t(), File.Stat.t(), stat_options()) :: :ok

write_stat/3 相同,但如果失敗,會引發 File.Error 例外。否則傳回 :ok