檢視原始碼 file (kernel v10.2)
檔案介面模組。
此模組提供檔案系統的介面。
警告
檔案操作僅在通過同一個檔案伺服器時才保證具有原子性。在某些作業系統上,例如在 Windows 上重新命名現有檔案,或在撰寫時在任何作業系統上進行
write_file_info/2
,NIF或其他作業系統處理序可能會觀察到某些操作的中間步驟。
關於檔案名稱編碼,Erlang VM 可以兩種模式運作。可以使用函式native_name_encoding/0
查詢目前模式。它會傳回 latin1
或 utf8
。
在 latin1
模式下,Erlang VM 不會變更檔案名稱的編碼。在 utf8
模式下,檔案名稱可以包含大於 255 的 Unicode 字元,並且 VM 會將檔案名稱來回轉換為原生檔案名稱編碼(通常為 UTF-8,但在 Windows 上為 UTF-16)。
預設模式取決於作業系統。Windows、MacOS X 和 Android 強制執行一致的檔案名稱編碼,因此 VM 使用 utf8
模式。
在具有透明命名功能的作業系統上(例如,除 MacOS X 之外的所有 Unix 系統),如果終端機支援 UTF-8,則預設為 utf8
,否則為 latin1
。可以使用 +fnl
(強制 latin1
模式)或 +fnu
(強制 utf8
模式)在啟動 erl
時覆寫預設值。
在具有透明命名功能的作業系統上,檔案的命名可能不一致,例如,某些檔案以 UTF-8 編碼,而其他檔案則以 ISO Latin-1 編碼。引入了*原始檔案名稱*的概念,以處理在 utf8
模式下執行時具有不一致命名的檔案系統。
原始檔案名稱是以二進位形式指定的檔案名稱。Erlang VM 不會在具有透明命名功能的系統上轉換以二進位形式指定的檔案名稱。
在 utf8
模式下執行時,函式 list_dir/1
和 read_link/1
永遠不會傳回原始檔案名稱。若要傳回包括原始檔案名稱在內的所有檔案名稱,請使用函式 list_dir_all/1
和 read_link_all/1
。
另請參閱 STDLIB 使用者指南中的關於原始檔案名稱的注意事項章節。
注意
檔案操作過去接受包含空字元(整數值為零)的檔案名稱。這會導致名稱被截斷,並且在某些情況下會混淆基本操作的參數。現在會拒絕在檔案名稱內包含空字元的檔案名稱,並且會導致基本檔案操作失敗。
POSIX 錯誤碼
eacces
- 拒絕存取eagain
- 資源暫時無法使用ebadf
- 錯誤的檔案號碼ebusy
- 檔案忙碌edquot
- 超過磁碟配額eexist
- 檔案已存在efault
- 系統呼叫引數中的錯誤位址efbig
- 檔案過大eintr
- 系統呼叫中斷einval
- 無效的引數eio
- I/O 錯誤eisdir
- 對目錄的非法操作eloop
- 符號連結層級太多emfile
- 開啟的檔案太多emlink
- 連結太多enametoolong
- 檔案名稱過長enfile
- 檔案表溢位enodev
- 沒有此裝置enoent
- 沒有此檔案或目錄enomem
- 記憶體不足enospc
- 裝置上沒有剩餘空間enotblk
- 需要區塊裝置enotdir
- 不是目錄enotsup
- 不支援的操作enxio
- 沒有此裝置或位址eperm
- 不是擁有者epipe
- 管道斷裂erofs
- 唯讀檔案系統espipe
- 無效的搜尋esrch
- 沒有此處理序estale
- 過時的遠端檔案控制代碼exdev
- 跨裝置連結
效能
為了提高效能,建議使用原始檔案。
一般的檔案實際上是一個處理序,因此它可以當做 I/O 裝置使用(請參閱 io
)。因此,當資料寫入一般檔案時,將資料傳送到檔案處理序,會複製所有非二進位的資料。因此,建議以二進位模式開啟檔案並寫入二進位。如果檔案在另一個節點上開啟,或如果檔案伺服器做為另一個節點檔案伺服器的從屬伺服器執行,也會複製二進位。
注意
原始檔案使用節點主機的檔案系統。對於一般檔案(非原始檔案),檔案伺服器會用來尋找檔案,並且如果節點做為另一個節點檔案伺服器的從屬伺服器執行其檔案伺服器,並且另一個節點在其他主機上執行,則它們可能具有不同的檔案系統。但是,這很少是一個問題。
可以為 open/2
提供選項 delayed_write
和 read_ahead
來開啟快取,這將減少作業系統呼叫的次數,並大幅提高小型讀寫的效能。但是,額外負荷不會完全消失,最好將檔案操作的次數保持在最低限度。作為一個假設的範例,以下函式在測試時寫入 4MB 需要 2.5 秒
create_file_slow(Name) ->
{ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
create_file_slow_1(Fd, 4 bsl 20),
file:close(Fd).
create_file_slow_1(_Fd, 0) ->
ok;
create_file_slow_1(Fd, M) ->
ok = file:write(Fd, <<0>>),
create_file_slow_1(Fd, M - 1).
以下功能相同的程式碼每次呼叫 write/2
時寫入 128 個位元組,因此在 0.08 秒內完成相同的工作,速度大約快 30 倍
create_file(Name) ->
{ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
create_file_1(Fd, 4 bsl 20),
file:close(Fd),
ok.
create_file_1(_Fd, 0) ->
ok;
create_file_1(Fd, M) when M >= 128 ->
ok = file:write(Fd, <<0:(128)/unit:8>>),
create_file_1(Fd, M - 128);
create_file_1(Fd, M) ->
ok = file:write(Fd, <<0:(M)/unit:8>>),
create_file_1(Fd, M - 1).
在寫入資料時,寫入二進位列表通常比寫入整數列表更有效率。寫入之前不需要展平深度列表。在 Unix 主機上,如果可能,會使用分散式輸出,該輸出會在一個操作中寫入一組緩衝區。透過這種方式,write(FD, [Bin1, Bin2 | Bin3])
會寫入二進位的內容,而完全不複製資料,除非可能在作業系統核心的深處。
警告
如果在存取使用模組
io
開啟的檔案時發生錯誤,則處理檔案的處理序會結束。如果處理序稍後嘗試存取已結束的檔案處理序,則可能會停滯。這將在未來的版本中修正。
另請參閱
摘要
類型
必須表示有效的日期和時間。
從 file
API 函式傳回的檔案名稱。
從 file
API 函式傳回的檔案名稱。
由 open/2
傳回的 IO 裝置。
處理 I/O 通訊協定的處理序。
用做 file
API 函式輸入的檔案名稱。
一個原子,其名稱來自 Unix 中使用的 POSIX 錯誤碼以及大多數 C 編譯器的執行階段程式庫。
函式
advise/4
可用來宣告未來以特定模式存取檔案資料的意圖,從而允許作業系統執行適當的最佳化。
allocate/3
可用來為檔案預先配置空間。
變更檔案的群組。請參閱 write_file_info/2
。
變更檔案的權限。請參閱 write_file_info/2
。
變更檔案的擁有者。請參閱 write_file_info/2
。
變更檔案的擁有者和群組。請參閱 write_file_info/2
。
變更檔案的修改和存取時間。請參閱 write_file_info/2
。
變更檔案的修改和上次存取時間。請參閱 write_file_info/2
。
關閉 IoDevice
參照的檔案。它大多會傳回 ok
,但某些嚴重的錯誤(例如記憶體不足)除外。
從 Filename
讀取以 .
分隔的 Erlang 詞彙。傳回下列其中一項
將 ByteCount
個位元組從 Source
複製到 Destination
。Source
和 Destination
參照檔案名稱,或例如來自 open/2
的 IO 裝置。
確保作業系統(而非 Erlang 執行階段系統)所保留的任何緩衝區都寫入磁碟。在許多方面,它類似於 fsync
,但它不會更新檔案的某些中繼資料,例如存取時間。在某些平台上,此函式無效。
嘗試刪除目錄 Dir
。目錄必須為空才能刪除。如果成功,則傳回 ok
。
刪除檔案或目錄 File
。如果 File
是目錄,則會先以遞迴方式刪除其內容。傳回
嘗試刪除檔案 Filename
。如果成功,則傳回 ok
。
從 Filename
讀取並評估 Erlang 表達式,這些表達式以 .
分隔(或 ,
,一連串的表達式也算是一個表達式)。評估的結果不會回傳;檔案中的任何表達式序列都必須是為了它的副作用而存在。
給定此模組中任何函式返回的錯誤原因,返回一個以英文描述錯誤的字串。
返回 {ok, Dir}
,其中 Dir
是檔案伺服器的目前工作目錄。
返回 {ok, Dir}
或 {error, Reason}
,其中 Dir
是指定磁碟機的目前工作目錄。
列出目錄中的所有檔案,*除了*具有原始檔名的檔案。如果成功,返回 {ok, Filenames}
,否則返回 {error, Reason}
。Filenames
是目錄中所有檔案名稱的列表。這些名稱未排序。
嘗試建立目錄 Dir
。遺失的父目錄*不會*被建立。如果成功,返回 ok
。
在支援連結的平台上 (Unix 和 Windows),從 Existing
建立一個硬連結到 New
。如果連結成功建立,此函式返回 ok
,否則返回 {error, Reason}
。在不支援連結的平台上,會返回 {error,enotsup}
。
在支援符號連結的平台上 (大多數 Unix 系統和 Windows,從 Vista 開始),建立一個符號連結 New
到檔案或目錄 Existing
。Existing
不一定要存在。如果連結成功建立,返回 ok
,否則返回 {error, Reason}
。在不支援符號連結的平台上,會返回 {error, enotsup}
。
以 Modes
決定的模式開啟檔案 File
,Modes
可以包含以下一個或多個選項
搜尋路徑 Path
(目錄名稱的列表),直到找到檔案 Filename
為止。如果 Filename
是絕對檔名,則會忽略 Path
。然後從檔案中讀取以 .
分隔的 Erlang 詞彙。
搜尋路徑 Path
(目錄名稱的列表),直到找到檔案 Filename
為止。如果 Filename
是絕對檔名,則會忽略 Path
。然後從檔案中讀取並評估 Erlang 表達式,這些表達式以 .
分隔(或 ,
,一連串的表達式也算是一個表達式)。評估的結果不會回傳;檔案中的任何表達式序列都必須是為了它的副作用而存在。
搜尋路徑 Path
(目錄名稱的列表),直到找到檔案 Filename
為止。如果 Filename
是絕對檔名,則會忽略 Path
。然後以 Modes
決定的模式開啟檔案。
搜尋路徑 Path
(目錄名稱的列表),直到找到檔案 Filename
為止。如果 Filename
是絕對檔名,則會忽略 Path
。然後從檔案中讀取並評估 Erlang 表達式,這些表達式以 .
分隔(或 ,
,一連串的表達式也算是一個表達式)。
與 path_script/2
相同,但在評估時會使用變數綁定 Bindings
。關於變數綁定,請參閱 erl_eval
。
將 IoDevice
參照的檔案位置設定為 Location
。如果成功,返回 {ok, NewPosition}
(作為絕對偏移),否則返回 {error, Reason}
。Location
是下列其中之一
在一個操作中執行一連串的 pread/3
,這比一次呼叫一個更有效率。返回 {ok, [Data, ...]}
或 {error, Reason}
,其中每個 Data
,對應的 pread
的結果,會是一個列表或二進制,取決於檔案的模式,或是如果請求的位置超出檔案結尾,則返回 eof
。
將 position/2
和 read/2
合併在一個操作中,這比一次呼叫一個更有效率。
在一個操作中執行一連串的 pwrite/3
,這比一次呼叫一個更有效率。返回 ok
或 {error, {N, Reason}}
,其中 N
是失敗前成功寫入的次數。
將 position/2
和 write/2
合併在一個操作中,這比一次呼叫一個更有效率。
從 IoDevice
參照的檔案讀取 Number
個位元組/字元。
返回 {ok, Binary}
,其中 Binary
是一個包含 Filename
內容的二進制資料物件,或是如果發生錯誤,返回 {error, Reason}
。
檢索檔案的相關資訊。如果成功,返回 {ok, FileInfo}
,否則返回 {error, Reason}
。
從 IoDevice
參照的檔案讀取一行位元組/字元。
如果 Name
參照的是符號連結,則返回 {ok, Filename}
,否則返回 {error, Reason}
。在不支援符號連結的平台上,返回值為 {error,enotsup}
。
功能類似 read_file_info/1,2
,除了如果 Name
是符號連結,關於連結的資訊會返回到 file_info
記錄中,並且記錄的 type
欄位會設定為 symlink
。
嘗試將檔案 Source
重新命名為 Destination
。它可以用於在目錄之間移動檔案(和目錄),但僅指定目的地是不夠的。還必須指定目的地的檔名。例如,如果 bar
是一個普通檔案,並且 foo
和 baz
是目錄,則 rename("foo/bar", "baz")
會返回錯誤,但 rename("foo/bar", "baz/bar")
會成功。如果成功,返回 ok
。
從檔案中讀取並評估 Erlang 表達式,這些表達式以 .
分隔(或 ,
,一連串的表達式也算是一個表達式)。
將檔案 Filename
發送到 Socket
。如果成功,返回 {ok, BytesSent}
,否則返回 {error, Reason}
。
從 RawFile
參照的檔案中,從 Offset
開始,將 Bytes
發送到 Socket
。如果成功,返回 {ok, BytesSent}
,否則返回 {error, Reason}
。如果 Bytes
設定為 0
,則會發送指定 Offset
後的所有資料。
將檔案伺服器的目前工作目錄設定為 Dir
。如果成功,返回 ok
。
確保作業系統 (而不是 Erlang 執行階段系統) 保留的任何緩衝區都寫入到磁碟中。在某些平台上,此函式可能沒有任何作用。
在目前位置截斷 IoDevice
參照的檔案。如果成功,返回 ok
,否則返回 {error, Reason}
。
將 Bytes
寫入到 IoDevice
參照的檔案中。此函式是唯一可以寫入以 raw
模式開啟的檔案的方式 (雖然它也適用於正常開啟的檔案)。如果成功,返回 ok
,否則返回 {error, Reason}
。
將 iodata
詞彙 Bytes
的內容寫入到檔案 Filename
。如果檔案不存在,則會建立檔案。如果檔案存在,則會覆寫先前的內容。如果成功,返回 ok
,否則返回 {error, Reason}
。
與 write_file/2
相同,但會採用第三個引數 Modes
,一個可能模式的列表,請參閱 open/2
。模式標記 binary
和 write
是隱含的,因此不應使用它們。
變更檔案資訊。如果成功,返回 ok
,否則返回 {error, Reason}
。
型別
-type date_time() :: calendar:datetime().
必須表示有效的日期和時間。
-type delete_option() :: raw.
-type fd() :: file_descriptor().
檔案描述符,表示以 raw
模式開啟的檔案。
-type file_info() :: #file_info{size :: non_neg_integer() | undefined, type :: device | directory | other | regular | symlink | undefined, access :: read | write | read_write | none | undefined, atime :: file:date_time() | non_neg_integer() | undefined, mtime :: file:date_time() | non_neg_integer() | undefined, ctime :: file:date_time() | non_neg_integer() | undefined, mode :: non_neg_integer() | undefined, links :: non_neg_integer() | undefined, major_device :: non_neg_integer() | undefined, minor_device :: non_neg_integer() | undefined, inode :: non_neg_integer() | undefined, uid :: non_neg_integer() | undefined, gid :: non_neg_integer() | undefined}.
-type file_info_option() :: {time, local} | {time, universal} | {time, posix} | raw.
-type filename() :: string().
從 file
API 函式傳回的檔案名稱。
請參閱 name_all/0
類型的文件。
從 file
API 函式傳回的檔案名稱。
請參閱 name_all/0
類型的文件。
由 open/2
傳回的 IO 裝置。
預設會回傳 io_server/0
,如果給定 raw
選項,則回傳 fd/0
。
-type io_server() :: pid().
處理 I/O 通訊協定的處理序。
-type mode() :: read | write | append | exclusive | raw | binary | {delayed_write, Size :: non_neg_integer(), Delay :: non_neg_integer()} | delayed_write | {read_ahead, Size :: pos_integer()} | read_ahead | compressed | compressed_one | {encoding, unicode:encoding()} | sync.
用做 file
API 函式輸入的受限檔案名稱。
如果虛擬機處於 Unicode 檔名模式,則允許 string/0
和 char/0
大於 255。另請參閱 name_all/0
類型的文件。
用做 file
API 函式輸入的檔案名稱。
如果虛擬機處於 Unicode 檔名模式,則允許字元大於 255。RawFilename
是不受 Unicode 轉換的檔名,表示它可以包含不符合檔案系統預期 Unicode 編碼的字元 (即,儘管虛擬機以 Unicode 檔名模式啟動,仍可包含非 UTF-8 字元)。檔名中(甚至在結尾)不允許空字元 (整數值為零)。
-type posix() ::
eacces | eagain | ebadf | ebadmsg | ebusy | edeadlk | edeadlock | edquot | eexist | efault |
efbig | eftype | eintr | einval | eio | eisdir | eloop | emfile | emlink | emultihop |
enametoolong | enfile | enobufs | enodev | enolck | enolink | enoent | enomem | enospc |
enosr | enostr | enosys | enotblk | enotdir | enotsup | enxio | eopnotsupp | eoverflow |
eperm | epipe | erange | erofs | espipe | esrch | estale | etxtbsy | exdev.
一個原子,其名稱來自 Unix 中使用的 POSIX 錯誤碼以及大多數 C 編譯器的執行階段程式庫。
-type posix_file_advise() :: normal | sequential | random | no_reuse | will_need | dont_need.
-type read_file_option() :: raw.
-type sendfile_option() :: {chunk_size, non_neg_integer()} | {use_threads, boolean()}.
函式
-spec advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason} when IoDevice :: io_device(), Offset :: integer(), Length :: integer(), Advise :: posix_file_advise(), Reason :: posix() | badarg.
advise/4
可用來宣告未來以特定模式存取檔案資料的意圖,從而允許作業系統執行適當的最佳化。
在某些平台上,此函式可能沒有作用。
-spec allocate(File, Offset, Length) -> ok | {error, posix()} when File :: io_device(), Offset :: non_neg_integer(), Length :: non_neg_integer().
allocate/3
可用來為檔案預先配置空間。
此函式僅在提供此功能的平台上成功。
-spec change_group(Filename, Gid) -> ok | {error, Reason} when Filename :: name_all(), Gid :: integer(), Reason :: posix() | badarg.
變更檔案的群組。請參閱 write_file_info/2
。
-spec change_mode(Filename, Mode) -> ok | {error, Reason} when Filename :: name_all(), Mode :: integer(), Reason :: posix() | badarg.
變更檔案的權限。請參閱 write_file_info/2
。
-spec change_owner(Filename, Uid) -> ok | {error, Reason} when Filename :: name_all(), Uid :: integer(), Reason :: posix() | badarg.
變更檔案的擁有者。請參閱 write_file_info/2
。
-spec change_owner(Filename, Uid, Gid) -> ok | {error, Reason} when Filename :: name_all(), Uid :: integer(), Gid :: integer(), Reason :: posix() | badarg.
變更檔案的擁有者和群組。請參閱 write_file_info/2
。
-spec change_time(Filename, Mtime) -> ok | {error, Reason} when Filename :: name_all(), Mtime :: date_time(), Reason :: posix() | badarg.
變更檔案的修改和存取時間。請參閱 write_file_info/2
。
-spec change_time(Filename, Atime, Mtime) -> ok | {error, Reason} when Filename :: name_all(), Atime :: date_time(), Mtime :: date_time(), Reason :: posix() | badarg.
變更檔案的修改和上次存取時間。請參閱 write_file_info/2
。
-spec close(IoDevice) -> ok | {error, Reason} when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.
關閉 IoDevice
參照的檔案。它大多會傳回 ok
,但某些嚴重的錯誤(例如記憶體不足)除外。
請注意,如果開啟檔案時使用了選項 delayed_write
,則 close/1
可能會回傳舊的寫入錯誤,甚至不會嘗試關閉檔案。請參閱 open/2
。
-spec consult(Filename) -> {ok, Terms} | {error, Reason} when Filename :: name_all(), Terms :: [term()], Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
從 Filename
讀取以 .
分隔的 Erlang 詞彙。傳回下列其中一項
{ok, Terms}
- 檔案已成功讀取。{error, atom()}
- 開啟檔案或讀取檔案時發生錯誤。如需典型錯誤代碼列表,請參閱open/2
。{error, {Line, Mod, Term}}
- 解釋檔案中的 Erlang 詞彙時發生錯誤。若要將三元素元組轉換為錯誤的英文描述,請使用format_error/1
。
範例
f.txt: {person, "kalle", 25}.
{person, "pelle", 30}.
1> file:consult("f.txt").
{ok,[{person,"kalle",25},{person,"pelle",30}]}
Filename
的編碼可透過註解設定,如 epp
中所述。
-spec copy(Source, Destination) -> {ok, BytesCopied} | {error, Reason} when Source :: io_device() | Filename | {Filename, Modes}, Destination :: io_device() | Filename | {Filename, Modes}, Filename :: name_all(), Modes :: [mode()], BytesCopied :: non_neg_integer(), Reason :: posix() | badarg | terminated.
-spec copy(Source, Destination, ByteCount) -> {ok, BytesCopied} | {error, Reason} when Source :: io_device() | Filename | {Filename, Modes}, Destination :: io_device() | Filename | {Filename, Modes}, Filename :: name_all(), Modes :: [mode()], ByteCount :: non_neg_integer() | infinity, BytesCopied :: non_neg_integer(), Reason :: posix() | badarg | terminated.
將 ByteCount
個位元組從 Source
複製到 Destination
。Source
和 Destination
參照檔案名稱,或例如來自 open/2
的 IO 裝置。
引數 Modes
是可能模式的列表,請參閱 open/2
,預設為 []
。
如果 Source
和 Destination
皆參照到檔名,則會分別將 [read, binary]
和 [write, binary]
加入其模式列表的最前面,以最佳化複製。
如果 Source
參照到檔名,則會在複製前將 read
模式加入模式列表的最前面,並在完成時關閉。
如果 Destination
參照到檔名,則會在複製前將 write
模式加入模式列表的最前面,並在完成時關閉。
回傳 {ok, BytesCopied}
,其中 BytesCopied
是複製的位元組數,如果來源遇到檔案結尾,則該數值可能小於 ByteCount
。如果作業失敗,則回傳 {error, Reason}
。
-spec datasync(IoDevice) -> ok | {error, Reason} when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.
確保作業系統(而非 Erlang 執行階段系統)所保留的任何緩衝區都寫入磁碟。在許多方面,它類似於 fsync
,但它不會更新檔案的某些中繼資料,例如存取時間。在某些平台上,此函式無效。
存取資料庫或記錄檔的應用程式通常會寫入一小段資料片段 (例如,記錄檔中的一行),然後立即呼叫 fsync()
,以確保寫入的資料實際儲存在硬碟上。不幸的是,fsync()
總是會啟動兩個寫入作業:一個用於新寫入的資料,另一個用於更新儲存在 inode
中的修改時間。如果修改時間不是交易概念的一部分,則可以使用 fdatasync()
來避免不必要的 inode
磁碟寫入作業。
此呼叫僅在某些 POSIX 系統中可用,它會導致呼叫 fsync()
,或者在未提供 fdatasync()
系統呼叫的系統中沒有作用。
嘗試刪除目錄 Dir
。目錄必須為空才能刪除。如果成功,則傳回 ok
。
典型的錯誤原因
eacces
-Dir
的父目錄缺少搜尋或寫入權限。eexist
- 目錄不是空的。enoent
- 目錄不存在。enotdir
-Dir
的元件不是目錄。在某些平台上,會改為回傳enoent
。einval
- 嘗試刪除目前目錄。在某些平台上,會改為回傳eacces
。
刪除檔案或目錄 File
。如果 File
是目錄,則會先以遞迴方式刪除其內容。傳回
ok
- 作業完成且無錯誤。{error, posix()}
- 存取或刪除File
時發生錯誤。如果無法刪除File
底下的某些檔案或目錄,則無法刪除File
,因為它不是空的,並且會回傳{error, eexist}
。
-spec delete(Filename) -> ok | {error, Reason} when Filename :: name_all(), Reason :: posix() | badarg.
等同於 delete(Filename, [])
。
-spec delete(Filename, Opts) -> ok | {error, Reason} when Filename :: name_all(), Opts :: [delete_option()], Reason :: posix() | badarg.
嘗試刪除檔案 Filename
。如果成功,則傳回 ok
。
如果設定選項 raw
,則不會呼叫檔案伺服器。這在檔案伺服器尚未註冊的早期啟動階段中特別有用,以便仍然能夠刪除本機檔案。
典型的錯誤原因
enoent
- 檔案不存在。eacces
- 檔案或其其中一個父目錄缺少權限。eperm
- 檔案是目錄,且使用者不是超級使用者。enotdir
- 檔名的元件不是目錄。在某些平台上,會改為回傳enoent
。einval
-Filename
的類型不正確,例如元組。
警告
在未來的版本中,引數
Filename
的類型錯誤可能會產生例外狀況。
-spec eval(Filename) -> ok | {error, Reason} when Filename :: name_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
從 Filename
讀取並評估 Erlang 表達式,這些表達式以 .
分隔(或 ,
,一連串的表達式也算是一個表達式)。評估的結果不會回傳;檔案中的任何表達式序列都必須是為了它的副作用而存在。
回傳下列其中一項
ok
- 檔案已讀取並評估。{error, atom()}
- 開啟檔案或讀取檔案時發生錯誤。如需典型錯誤代碼列表,請參閱open/2
。{error, {Line, Mod, Term}}
- 解釋檔案中的 Erlang 運算式時發生錯誤。若要將三元素元組轉換為錯誤的英文描述,請使用format_error/1
。
Filename
的編碼可透過註解設定,如 epp
中所述。
-spec format_error(Reason) -> Chars when Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}, Chars :: string().
給定此模組中任何函式返回的錯誤原因,返回一個以英文描述錯誤的字串。
返回 {ok, Dir}
,其中 Dir
是檔案伺服器的目前工作目錄。
注意
在極少數情況下,此函式在 Unix 上可能會失敗。如果目前目錄的父目錄不存在讀取權限,則可能會發生此情況。
典型的錯誤原因
eacces
- 目前目錄的其中一個父目錄缺少讀取權限。
-spec get_cwd(Drive) -> {ok, Dir} | {error, Reason} when Drive :: string(), Dir :: filename(), Reason :: posix() | badarg.
返回 {ok, Dir}
或 {error, Reason}
,其中 Dir
是指定磁碟機的目前工作目錄。
Drive
的格式應為 Letter:
,例如 c:
。
在沒有目前磁碟機概念的平台 (例如 Unix) 上回傳 {error, enotsup}
。
典型的錯誤原因
enotsup
- 作業系統沒有磁碟機的概念。eacces
- 磁碟機不存在。einval
-Drive
的格式無效。
-spec list_dir(Dir) -> {ok, Filenames} | {error, Reason} when Dir :: name_all(), Filenames :: [filename()], Reason :: posix() | badarg | {no_translation, Filename :: unicode:latin1_binary()}.
列出目錄中的所有檔案,*除了*具有原始檔名的檔案。如果成功,返回 {ok, Filenames}
,否則返回 {error, Reason}
。Filenames
是目錄中所有檔案名稱的列表。這些名稱未排序。
典型的錯誤原因
eacces
-Dir
或其其中一個父目錄缺少搜尋或寫入權限。enoent
- 目錄不存在。{no_translation, Filename}
-Filename
是以 ISO Latin-1 編碼的字元之binary/0
,並且虛擬機以參數+fnue
啟動。
-spec list_dir_all(Dir) -> {ok, Filenames} | {error, Reason} when Dir :: name_all(), Filenames :: [filename_all()], Reason :: posix() | badarg.
列出目錄中的所有檔案,包括使用原始檔名的檔案。如果成功,則返回 {ok, Filenames}
,否則返回 {error, Reason}
。Filenames
是目錄中所有檔案名稱的列表。這些名稱未經排序。
典型的錯誤原因
eacces
-Dir
或其其中一個父目錄缺少搜尋或寫入權限。enoent
- 目錄不存在。
嘗試建立目錄 Dir
。遺失的父目錄*不會*被建立。如果成功,返回 ok
。
典型的錯誤原因
eacces
-Dir
的父目錄缺少搜尋或寫入權限。eexist
- 名為Dir
的檔案或目錄已存在。enoent
-Dir
的某個組成部分不存在。enospc
- 裝置上沒有剩餘空間。enotdir
-Dir
的元件不是目錄。在某些平台上,會改為回傳enoent
。
-spec make_link(Existing, New) -> ok | {error, Reason} when Existing :: name_all(), New :: name_all(), Reason :: posix() | badarg.
在支援連結的平台上 (Unix 和 Windows),從 Existing
建立一個硬連結到 New
。如果連結成功建立,此函式返回 ok
,否則返回 {error, Reason}
。在不支援連結的平台上,會返回 {error,enotsup}
。
典型的錯誤原因
eacces
- 缺少Existing
或New
的父目錄的讀取或寫入權限。eexist
-New
已存在。enotsup
- 此平台上不支援硬連結。
-spec make_symlink(Existing, New) -> ok | {error, Reason} when Existing :: name_all(), New :: name_all(), Reason :: posix() | badarg.
在支援符號連結的平台上 (大多數 Unix 系統和 Windows,從 Vista 開始),建立一個符號連結 New
到檔案或目錄 Existing
。Existing
不一定要存在。如果連結成功建立,返回 ok
,否則返回 {error, Reason}
。在不支援符號連結的平台上,會返回 {error, enotsup}
。
典型的錯誤原因
eacces
- 缺少Existing
或New
的父目錄的讀取或寫入權限。eexist
-New
已存在。enotsup
- 此平台上不支援符號連結。eperm
- 使用者沒有建立符號連結的權限(在 Windows 上為SeCreateSymbolicLinkPrivilege
)。
-spec native_name_encoding() -> latin1 | utf8.
返回檔案名稱編碼模式。如果為 latin1
,系統不轉換任何檔案名稱。如果為 utf8
,檔案名稱會來回轉換為原生檔案名稱編碼(通常為 UTF-8,但在 Windows 上為 UTF-16)。
-spec open(File, Modes) -> {ok, IoDevice} | {error, Reason} when File :: Filename | iodata(), Filename :: name_all(), Modes :: [mode() | ram | directory], IoDevice :: io_device(), Reason :: posix() | badarg | system_limit.
以 Modes
決定的模式開啟檔案 File
,Modes
可以包含以下一個或多個選項
read
- 開啟檔案以進行讀取,該檔案必須存在。write
- 開啟檔案以進行寫入。如果檔案不存在,則會建立該檔案。如果檔案存在,且write
未與read
組合使用,則會截斷該檔案。append
- 開啟檔案以進行寫入。如果檔案不存在,則會建立該檔案。每次寫入以append
開啟的檔案的操作都會在檔案結尾處進行。exclusive
- 開啟檔案以進行寫入。如果檔案不存在,則會建立該檔案。如果檔案存在,則返回{error, eexist}
。警告
此選項不保證在不正確支援
O_EXCL
的檔案系統(如 NFS)上的互斥性。除非您知道檔案系統支援此選項,否則請勿依賴此選項(一般而言,本機檔案系統是安全的)。raw
- 允許更快速地存取檔案,因為不需要 Erlang 程序來處理檔案。但是,以這種方式開啟的檔案具有以下限制io
模組中的函數無法使用,因為它們只能與 Erlang 程序交談。請改用read/2
、read_line/1
和write/2
等函數。- 尤其是在
raw
檔案上使用read_line/1
時,建議將此選項與選項{read_ahead, Size}
組合使用,因為在沒有緩衝的情況下,以行為導向的 I/O 效率較低。 - 只有開啟檔案的 Erlang 程序才能使用它。
- 無法使用遠端的 Erlang 檔案伺服器。執行 Erlang 節點的電腦必須能夠存取檔案系統(直接或透過 NFS)。
binary
- 對檔案的讀取操作會傳回二進位資料,而不是列表。{delayed_write, Size, Delay}
- 後續write/2
呼叫中的資料會被緩衝,直到至少緩衝了Size
個位元組,或直到最舊的緩衝資料達到Delay
毫秒。然後,所有緩衝的資料都會在一個作業系統呼叫中寫入。緩衝的資料也會在執行write/2
以外的其他檔案操作之前清除。此選項的目的是透過減少作業系統呼叫的次數來提高效能。因此,
write/2
呼叫的大小必須明顯小於Size
,並且不會被過多的其他檔案操作穿插。使用此選項時,
write/2
呼叫的結果可能會過早地回報為成功,並且如果發生寫入錯誤,則該錯誤會回報為下一個未執行的檔案操作的結果。例如,當使用
delayed_write
時,在多次呼叫write/2
之後,close/1
可能會返回{error, enospc}
,因為磁碟上沒有足夠的空間來儲存先前寫入的資料。close/1
可能必須再次呼叫,因為該檔案仍然開啟。delayed_write
- 與{delayed_write, Size, Delay}
相同,只是Size
和Delay
使用合理的預設值(大約 64 KB,2 秒)。{read_ahead, Size}
- 啟用讀取資料緩衝。如果read/2
呼叫的位元組數明顯小於Size
,則對作業系統的讀取操作仍然會執行Size
位元組的區塊。額外的資料會被緩衝,並在後續的read/2
呼叫中傳回,從而減少作業系統呼叫次數,達到效能提升的效果。read_ahead
緩衝區也被raw
模式中的函數read_line/1
大量使用,因此,當使用該函數存取原始檔案時,建議使用此選項(基於效能考量)。如果
read/2
呼叫的大小不顯著小於或甚至大於Size
個位元組,則預期不會有任何效能提升。read_ahead
- 與{read_ahead, Size}
相同,只是Size
使用合理的預設值(大約 64 KB)。compressed
- 可以讀取或寫入 gzip 壓縮檔案。選項compressed
必須與read
或write
組合使用,但不能同時使用。請注意,使用read_file_info/1
取得的檔案大小可能與可以從壓縮檔案讀取的位元組數不符。compressed_one
- 讀取 gzip 壓縮檔案的一個成員。選項compressed_one
只能與read
組合使用。{encoding, Encoding}
- 使檔案能夠自動將字元轉換為特定的(Unicode)編碼,以及從該編碼轉換。請注意,提供給write/2
或由read/2
傳回的資料仍然是以位元組為導向的;此選項僅表示資料在磁碟檔案中的儲存方式。根據編碼的不同,偏好不同的讀取和寫入資料的方法。
latin1
的預設編碼表示使用此模組(file
)來讀寫資料,因為此處提供的介面使用以位元組為導向的資料。使用其他(Unicode)編碼使io
函數get_chars
、get_line
和put_chars
更適合,因為它們可以使用完整的 Unicode 範圍。如果資料以無法轉換為指定編碼的格式傳送至
io_device/0
,或者如果資料由以無法處理資料字元範圍的格式返回資料的函數讀取,則會發生錯誤並且檔案關閉。Encoding
的允許值latin1
- 預設編碼。提供給檔案的位元組(即write/2
)會「按原樣」寫入檔案。同樣地,從檔案讀取的位元組(即read/2
)會「按原樣」返回。如果模組io
用於寫入,則檔案只能處理代碼點高達 255 的 Unicode 字元(ISO Latin-1 範圍)。unicode
或utf8
- 字元在寫入檔案或從檔案讀取之前,會被轉換為 UTF-8 編碼以及從 UTF-8 編碼轉換。以這種方式開啟的檔案可以使用函數read/2
讀取,只要檔案上儲存的資料沒有超出 ISO Latin-1 範圍 (0..255),但如果資料包含超出該範圍的 Unicode 代碼點,則會發生失敗。最好使用具有 Unicode 感知功能的模組io
中的函數讀取該檔案。透過任何方式寫入檔案的位元組在儲存到磁碟檔案之前,都會被轉換為 UTF-8 編碼。
utf16
或{utf16,big}
- 工作方式與unicode
相同,但會轉換為大端 UTF-16 或從大端 UTF-16 轉換,而不是 UTF-8。{utf16,little}
- 工作方式與unicode
相同,但會轉換為小端 UTF-16 或從小端 UTF-16 轉換,而不是 UTF-8。utf32
或{utf32,big}
- 工作方式與unicode
相同,但會轉換為大端 UTF-32 或從大端 UTF-32 轉換,而不是 UTF-8。{utf32,little}
- 工作方式與unicode
相同,但會轉換為小端 UTF-32 或從小端 UTF-32 轉換,而不是 UTF-8。
可以使用函數
io:setopts/2
「動態」變更檔案的Encoding
。因此,可以使用 latin1 編碼分析檔案(例如,用於 BOM),定位在 BOM 之後,然後在進一步讀取之前設定正確的編碼。有關識別 BOM 的函數,請參閱模組unicode
。此選項不允許用於
raw
檔案。ram
-File
必須是iodata/0
。傳回fd/0
,它允許模組file
在記憶體中將資料視為檔案進行操作。sync
- 在支援的平台上,會啟用 POSIXO_SYNC
同步 I/O 旗標或其平台相關的等效旗標(例如,Windows 上的FILE_FLAG_WRITE_THROUGH
),以便在資料實際寫入磁碟之前,對檔案的寫入會被封鎖。但是,請注意,此旗標的確切語意因平台而異。例如,Linux 或 Windows 都不保證在呼叫返回之前也會寫入所有檔案中繼資料。如需精確的語意,請查看您的平台文件詳細資訊。在不支援 POSIXO_SYNC
或等效項的平台上,使用sync
旗標會導致open
傳回{error, enotsup}
。directory
- 允許open
在目錄上工作。
返回
{ok, IoDevice}
- 檔案以要求的模式開啟。IoDevice
是對檔案的引用。{error, Reason}
- 無法開啟檔案。
IoDevice
實際上是處理該檔案的行程的 PID。這個行程會監控最初開啟檔案的行程(擁有者行程)。如果擁有者行程終止,檔案也會被關閉,且此行程本身也會終止。從此呼叫返回的 IoDevice
可以作為 I/O 函數的參數使用(請參閱 io
)。
警告
雖然此函數可用於開啟任何檔案,但我們建議不要將其用於 NFS 掛載的檔案、FIFO、裝置或類似的物件,因為它們可能導致 IO 線程永久掛起。
如果您的應用程式需要與這些類型的檔案互動,我們建議將這些部分獨立出來改為使用 port 程式。
注意
在舊版本的
file
中,模式是以原子read
、write
或read_write
之一來指定,而不是使用清單。為了向後相容性,這種方式仍然允許,但不應用於新的程式碼。另外請注意,模式清單中不允許使用read_write
。
典型的錯誤原因
enoent
- 檔案不存在。eacces
- 缺少讀取檔案或搜尋其中一個父目錄的權限。eisdir
- 指定的檔案是目錄。enotdir
- 檔案名稱的某個組成部分不是目錄,或者如果指定了directory
模式,則檔案名稱本身不是目錄。在某些平台上,會改為返回enoent
。enospc
- 裝置上沒有剩餘空間(如果指定了write
存取權)。
-spec path_consult(Path, Filename) -> {ok, Terms, FullName} | {error, Reason} when Path :: [Dir], Dir :: name_all(), Filename :: name_all(), Terms :: [term()], FullName :: filename_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
搜尋路徑 Path
(目錄名稱的列表),直到找到檔案 Filename
為止。如果 Filename
是絕對檔名,則會忽略 Path
。然後從檔案中讀取以 .
分隔的 Erlang 詞彙。
回傳下列其中一項
{ok, Terms, FullName}
- 檔案已成功讀取。FullName
是檔案的完整名稱。{error, enoent}
- 無法在Path
中的任何目錄中找到該檔案。{error, atom()}
- 開啟檔案或讀取檔案時發生錯誤。如需典型錯誤代碼列表,請參閱open/2
。{error, {Line, Mod, Term}}
- 解譯檔案中的 Erlang 術語時發生錯誤。使用format_error/1
將三元素元組轉換為錯誤的英文描述。
Filename
的編碼可以透過註解來設定,如 epp
中所述。
-spec path_eval(Path, Filename) -> {ok, FullName} | {error, Reason} when Path :: [Dir :: name_all()], Filename :: name_all(), FullName :: filename_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
搜尋路徑 Path
(目錄名稱的列表),直到找到檔案 Filename
為止。如果 Filename
是絕對檔名,則會忽略 Path
。然後從檔案中讀取並評估 Erlang 表達式,這些表達式以 .
分隔(或 ,
,一連串的表達式也算是一個表達式)。評估的結果不會回傳;檔案中的任何表達式序列都必須是為了它的副作用而存在。
回傳下列其中一項
{ok, FullName}
- 檔案已讀取並評估。FullName
是檔案的完整名稱。{error, enoent}
- 無法在Path
中的任何目錄中找到該檔案。{error, atom()}
- 開啟檔案或讀取檔案時發生錯誤。如需典型錯誤代碼列表,請參閱open/2
。{error, {Line, Mod, Term}}
- 解譯檔案中的 Erlang 表達式時發生錯誤。使用format_error/1
將三元素元組轉換為錯誤的英文描述。
Filename
的編碼可以透過註解來設定,如 epp
中所述。
-spec path_open(Path, Filename, Modes) -> {ok, IoDevice, FullName} | {error, Reason} when Path :: [Dir :: name_all()], Filename :: name_all(), Modes :: [mode() | directory], IoDevice :: io_device(), FullName :: filename_all(), Reason :: posix() | badarg | system_limit.
搜尋路徑 Path
(目錄名稱的列表),直到找到檔案 Filename
為止。如果 Filename
是絕對檔名,則會忽略 Path
。然後以 Modes
決定的模式開啟檔案。
回傳下列其中一項
{ok, IoDevice, FullName}
- 檔案已以請求的模式開啟。IoDevice
是對該檔案的參照,而FullName
是檔案的完整名稱。{error, enoent}
- 無法在Path
中的任何目錄中找到該檔案。{error, atom()}
- 無法開啟檔案。
-spec path_script(Path, Filename) -> {ok, Value, FullName} | {error, Reason} when Path :: [Dir :: name_all()], Filename :: name_all(), Value :: term(), FullName :: filename_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
搜尋路徑 Path
(目錄名稱的列表),直到找到檔案 Filename
為止。如果 Filename
是絕對檔名,則會忽略 Path
。然後從檔案中讀取並評估 Erlang 表達式,這些表達式以 .
分隔(或 ,
,一連串的表達式也算是一個表達式)。
回傳下列其中一項
{ok, Value, FullName}
- 檔案已讀取並評估。FullName
是檔案的完整名稱,而Value
是最後一個表達式的值。{error, enoent}
- 無法在Path
中的任何目錄中找到該檔案。{error, atom()}
- 開啟檔案或讀取檔案時發生錯誤。如需典型錯誤代碼列表,請參閱open/2
。{error, {Line, Mod, Term}}
- 解譯檔案中的 Erlang 表達式時發生錯誤。使用format_error/1
將三元素元組轉換為錯誤的英文描述。
Filename
的編碼可以透過註解來設定,如 epp
中所述。
-spec path_script(Path, Filename, Bindings) -> {ok, Value, FullName} | {error, Reason} when Path :: [Dir :: name_all()], Filename :: name_all(), Bindings :: erl_eval:binding_struct(), Value :: term(), FullName :: filename_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
與 path_script/2
相同,但在評估時會使用變數綁定 Bindings
。關於變數綁定,請參閱 erl_eval
。
-spec position(IoDevice, Location) -> {ok, NewPosition} | {error, Reason} when IoDevice :: io_device(), Location :: location(), NewPosition :: integer(), Reason :: posix() | badarg | terminated.
將 IoDevice
參照的檔案位置設定為 Location
。如果成功,返回 {ok, NewPosition}
(作為絕對偏移),否則返回 {error, Reason}
。Location
是下列其中之一
Offset
- 與{bof, Offset}
相同。{bof, Offset}
- 絕對偏移量。{cur, Offset}
- 從目前位置的偏移量。{eof, Offset}
- 從檔案結尾的偏移量。bof | cur | eof
- 與上述相同,但Offset
為 0。
請注意,偏移量是以位元組(而不是字元)計算。如果檔案開啟時使用的 encoding
不是 latin1
,則一個位元組不對應一個字元。在這種檔案中定位只能定位到已知的字元邊界。也就是說,定位到先前取得的目前位置、檔案的開頭/結尾,或透過其他方式(通常是檔案中的位元組順序標記,其具有已知的位元組大小)已知位於正確字元邊界上的其他位置。
典型的錯誤原因是
einval
- 要么Location
非法,要么評估為檔案中的負偏移量。請注意,如果產生的位置為負值,則結果為錯誤,並且在呼叫後,檔案位置未定義。
-spec pread(IoDevice, LocNums) -> {ok, DataL} | eof | {error, Reason} when IoDevice :: io_device(), LocNums :: [{Location :: location(), Number :: non_neg_integer()}], DataL :: [Data], Data :: string() | binary() | eof, Reason :: posix() | badarg | terminated.
在一個操作中執行一連串的 pread/3
,這比一次呼叫一個更有效率。返回 {ok, [Data, ...]}
或 {error, Reason}
,其中每個 Data
,對應的 pread
的結果,會是一個列表或二進制,取決於檔案的模式,或是如果請求的位置超出檔案結尾,則返回 eof
。
由於位置指定為位元組偏移量,因此當處理 encoding
設定為 latin1
以外的其他值時,請特別小心,因為在這種檔案上並非每個位元組位置都是有效的字元邊界。
-spec pread(IoDevice, Location, Number) -> {ok, Data} | eof | {error, Reason} when IoDevice :: io_device(), Location :: location(), Number :: non_neg_integer(), Data :: string() | binary(), Reason :: posix() | badarg | terminated.
將 position/2
和 read/2
合併在一個操作中,這比一次呼叫一個更有效率。
Location
僅允許在 raw
和 ram
模式下為整數。
在執行操作後,對於 raw
模式,檔案的目前位置是未定義的;對於 ram
模式,檔案的目前位置則是不變的。
由於位置指定為位元組偏移量,因此當處理 encoding
設定為 latin1
以外的其他值時,請特別小心,因為在這種檔案上並非每個位元組位置都是有效的字元邊界。
-spec pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}} when IoDevice :: io_device(), LocBytes :: [{Location :: location(), Bytes :: iodata()}], N :: non_neg_integer(), Reason :: posix() | badarg | terminated.
在一個操作中執行一連串的 pwrite/3
,這比一次呼叫一個更有效率。返回 ok
或 {error, {N, Reason}}
,其中 N
是失敗前成功寫入的次數。
當在 encoding
不是 latin1
的檔案中進行定位時,必須小心將位置設定在正確的字元邊界上。有關詳細資訊,請參閱 position/2
。
-spec pwrite(IoDevice, Location, Bytes) -> ok | {error, Reason} when IoDevice :: io_device(), Location :: location(), Bytes :: iodata(), Reason :: posix() | badarg | terminated.
將 position/2
和 write/2
合併在一個操作中,這比一次呼叫一個更有效率。
Location
僅允許在 raw
和 ram
模式下為整數。
在執行操作後,對於 raw
模式,檔案的目前位置是未定義的;對於 ram
模式,檔案的目前位置則是不變的。
當在 encoding
不是 latin1
的檔案中進行定位時,必須小心將位置設定在正確的字元邊界上。有關詳細資訊,請參閱 position/2
。
-spec read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason} when IoDevice :: io_device() | io:device(), Number :: non_neg_integer(), Data :: string() | binary(), Reason :: posix() | badarg | terminated | {no_translation, unicode, latin1}.
從 IoDevice
參照的檔案讀取 Number
個位元組/字元。
函數 read/2
、pread/3
和 read_line/1
是唯一可以從以 raw
模式開啟的檔案中讀取資料的方式(儘管它們也適用於正常開啟的檔案)。
對於 encoding
設定為 latin1
以外的值的檔案,一個字元可以用檔案中的多個位元組表示。參數 Number
始終表示從檔案中讀取的字元數量,而讀取 Unicode 檔案時,檔案中的位置可能會移動遠遠超出此數字。
此外,如果 encoding
設定為 latin1
以外的值,則如果資料包含大於 255 的字元,read/2
呼叫將會失敗,這就是為什麼在讀取此類檔案時,建議使用 io:get_chars/3
的原因。
此函數會返回
{ok, Data}
- 如果檔案以二進位模式開啟,則讀取的位元組會以二進位形式返回,否則會以清單形式返回。如果到達檔案結尾,則清單或二進位會短於請求的位元組數。eof
- 如果Number>0
且在任何資料都讀取之前就到達檔案結尾,則返回此值。{error, Reason}
- 發生錯誤。
典型的錯誤原因
ebadf
- 該檔案未開啟以進行讀取。{no_translation, unicode, latin1}
- 該檔案以latin1
以外的其他encoding
開啟,且檔案中的資料無法轉換為此函數返回的以位元組為導向的資料。
-spec read_file(Filename, Opts) -> {ok, Binary} | {error, Reason} when Filename :: name_all(), Opts :: [read_file_option()], Binary :: binary(), Reason :: posix() | badarg | terminated | system_limit.
返回 {ok, Binary}
,其中 Binary
是一個包含 Filename
內容的二進制資料物件,或是如果發生錯誤,返回 {error, Reason}
。
如果設定了選項 raw
,則不會呼叫檔案伺服器。
典型的錯誤原因
enoent
- 檔案不存在。eacces
- 缺少讀取檔案或搜尋其中一個父目錄的權限。eisdir
- 指定的檔案是目錄。enotdir
- 檔名的元件不是目錄。在某些平台上,會改為回傳enoent
。enomem
- 沒有足夠的記憶體來儲存檔案內容。
-spec read_file_info(File, Opts) -> {ok, FileInfo} | {error, Reason} when File :: name_all() | io_device(), Opts :: [file_info_option()], FileInfo :: file_info(), Reason :: posix() | badarg.
檢索檔案的相關資訊。如果成功,返回 {ok, FileInfo}
,否則返回 {error, Reason}
。
FileInfo
是一個記錄 file_info
,定義在 Kernel 包含檔案 file.hrl
中。在呼叫此函數的模組中包含以下指令
-include_lib("kernel/include/file.hrl").
在 atime
、mtime
和 ctime
中返回的時間類型取決於 Opts :: {time, Type}
中設定的時間類型,如下所示
local
- 返回當地時間。universal
- 返回世界標準時間。posix
- 返回自或早於 Unix 時間紀元(即 1970-01-01 00:00 UTC)的秒數。
預設值為 {time, local}
。
如果設定了選項 raw
,則不會呼叫檔案伺服器,且只會返回有關本機檔案的資訊。請注意,這會破壞此模組的原子性保證,因為它可能會與並行呼叫 write_file_info/1,2
競爭。
當此函數獲得的是 I/O 裝置而不是檔案名稱時,此選項無效。請先使用帶有 raw
模式的 open/2
取得檔案描述符。
注意
由於檔案時間在大多數作業系統上以 POSIX 時間儲存,因此使用選項
posix
查詢檔案資訊的速度會更快。
記錄 file_info
包含以下欄位
size =
non_neg_integer/0
- 檔案大小(以位元組為單位)。type = device | directory | other | regular
- 檔案的類型。從 read_link_info/1,2 返回時,也可以包含symlink
。access = read | write | read_write | none
- 目前系統對檔案的存取權限。atime =
date_time/0
|
non_neg_integer/0
- 上次讀取檔案的時間。mtime =
date_time/0
|
non_neg_integer/0
- 上次寫入檔案的時間。ctime =
date_time/0
|
non_neg_integer/0
- 此時間欄位的解讀取決於作業系統。在 Unix 上,它是上次變更檔案或inode
的時間。在 Windows 上,它是建立時間。mode =
non_neg_integer/0
- 檔案權限,為以下位元值的總和8#00400
- 讀取權限:擁有者8#00200
- 寫入權限:擁有者8#00100
- 執行權限:擁有者8#00040
- 讀取權限:群組8#00020
- 寫入權限:群組8#00010
- 執行權限:群組8#00004
- 讀取權限:其他8#00002
- 寫入權限:其他8#00001
- 執行權限:其他16#800
- 執行時設定使用者 ID16#400
- 執行時設定群組 ID
在 Unix 平台上,可能會設定除了上述列出的其他位元。
links =
non_neg_integer/0
- 到該檔案的連結數量 (對於沒有連結概念的檔案系統,這通常為 1)。major_device =
non_neg_integer/0
- 識別檔案所在的檔案系統。在 Windows 中,該數字表示磁碟機,如下所示:0 表示 A:,1 表示 B:,依此類推。minor_device =
non_neg_integer/0
- 僅在 Unix 上的字元裝置有效。在所有其他情況下,此欄位為零。inode =
non_neg_integer/0
- 給出inode
編號。在非 Unix 檔案系統上,此欄位為零。uid =
non_neg_integer/0
- 表示檔案的所有者。在非 Unix 檔案系統上,此欄位為零。gid =
non_neg_integer/0
- 給出檔案所有者所屬的群組。在非 Unix 檔案系統上,此欄位為零。
典型的錯誤原因
eacces
- 缺少檔案的其中一個父目錄的搜尋權限。enoent
- 檔案不存在。enotdir
- 檔名的元件不是目錄。在某些平台上,會改為回傳enoent
。
-spec read_line(IoDevice) -> {ok, Data} | eof | {error, Reason} when IoDevice :: io_device() | io:device(), Data :: string() | binary(), Reason :: posix() | badarg | terminated | {no_translation, unicode, latin1}.
從 IoDevice
參照的檔案讀取一行位元組/字元。
行的定義是以換行符號 (LF, \n
) 字元分隔,但任何後跟換行的歸位字元 (CR, \r
) 也會被視為單個 LF 字元(歸位字元會被靜默忽略)。返回的行包含 LF,但不包含任何緊隨 LF 的 CR。此行為與 io:get_line/2
的行為一致。如果到達檔案結尾且最後一行沒有 LF 結尾,則會返回沒有尾隨 LF 的行。
該函數可用於以 raw
模式開啟的檔案。但是,如果檔案沒有指定 {read_ahead, Size}
選項,則在 raw
檔案上使用它效率低下。因此,在開啟文字檔案以進行原始的行導向讀取時,強烈建議將 raw
和 {read_ahead, Size}
組合使用。
如果 encoding
設定為 latin1
以外的值,如果資料包含大於 255 的字元,read_line/1
呼叫將會失敗,因此在讀取此類檔案時,應優先使用 io:get_line/2
。
此函數會返回
{ok, Data}
- 返回檔案中的一行,包含尾隨的 LF,但 CRLF 序列會被替換為單個 LF(請參閱上文)。如果檔案以二進制模式開啟,則讀取的位元組會以二進制形式返回,否則會以列表形式返回。
eof
- 如果在可以讀取任何內容之前到達檔案結尾,則返回。{error, Reason}
- 發生錯誤。
典型的錯誤原因
ebadf
- 該檔案未開啟以進行讀取。{no_translation, unicode, latin1}
- 檔案以latin1
以外的encoding
開啟,並且檔案上的資料無法轉換為此函數返回的位元組導向資料。
-spec read_link(Name) -> {ok, Filename} | {error, Reason} when Name :: name_all(), Filename :: filename(), Reason :: posix() | badarg.
如果 Name
指的是不是原始檔名的符號連結,則返回 {ok, Filename}
,否則返回 {error, Reason}
。在不支援符號連結的平台上,返回值為 {error,enotsup}
。
典型的錯誤原因
einval
-Name
並非指符號連結,或者它所指的檔案名稱不符合預期的編碼。enoent
- 檔案不存在。enotsup
- 此平台上不支援符號連結。
-spec read_link_all(Name) -> {ok, Filename} | {error, Reason} when Name :: name_all(), Filename :: filename_all(), Reason :: posix() | badarg.
如果 Name
參照的是符號連結,則返回 {ok, Filename}
,否則返回 {error, Reason}
。在不支援符號連結的平台上,返回值為 {error,enotsup}
。
請注意,Filename
可以是列表或二進制。
典型的錯誤原因
einval
-Name
並非指符號連結。enoent
- 檔案不存在。enotsup
- 此平台上不支援符號連結。
-spec read_link_info(Name, Opts) -> {ok, FileInfo} | {error, Reason} when Name :: name_all(), Opts :: [file_info_option()], FileInfo :: file_info(), Reason :: posix() | badarg.
功能類似 read_file_info/1,2
,除了如果 Name
是符號連結,關於連結的資訊會返回到 file_info
記錄中,並且記錄的 type
欄位會設定為 symlink
。
如果設定 raw
選項,則不會呼叫檔案伺服器,並且僅返回有關本機檔案的資訊。請注意,這會破壞此模組的原子性保證,因為它可能會與同時呼叫 write_file_info/1,2
發生競爭。
如果 Name
不是符號連結,則此函數返回的結果與 read_file_info/1
相同。在不支援符號連結的平台上,此函數始終等效於 read_file_info/1
。
-spec rename(Source, Destination) -> ok | {error, Reason} when Source :: name_all(), Destination :: name_all(), Reason :: posix() | badarg.
嘗試將檔案 Source
重新命名為 Destination
。它可以用於在目錄之間移動檔案(和目錄),但僅指定目的地是不夠的。還必須指定目的地的檔名。例如,如果 bar
是一個普通檔案,並且 foo
和 baz
是目錄,則 rename("foo/bar", "baz")
會返回錯誤,但 rename("foo/bar", "baz/bar")
會成功。如果成功,返回 ok
。
注意
在大多數平台上,不允許重新命名已開啟的檔案 (請參閱下面的
eacces
)。
典型的錯誤原因
eacces
- 缺少Source
或Destination
的父目錄的讀取或寫入權限。在某些平台上,如果Source
或Destination
已開啟,則會給出此錯誤。eexist
-Destination
不是空目錄。在某些平台上,當Source
和Destination
的類型不同時,也會給出此錯誤。einval
-Source
是根目錄,或者Destination
是Source
的子目錄。eisdir
-Destination
是目錄,但Source
不是。enoent
-Source
不存在。enotdir
-Source
是目錄,但Destination
不是。exdev
-Source
和Destination
位於不同的檔案系統上。
-spec script(Filename) -> {ok, Value} | {error, Reason} when Filename :: name_all(), Value :: term(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
從檔案中讀取並評估 Erlang 表達式,這些表達式以 .
分隔(或 ,
,一連串的表達式也算是一個表達式)。
回傳下列其中一項
{ok, Value}
- 讀取並評估該檔案。Value
是最後一個表達式的值。{error, atom()}
- 開啟檔案或讀取檔案時發生錯誤。如需典型錯誤代碼列表,請參閱open/2
。{error, {Line, Mod, Term}}
- 解譯檔案中的 Erlang 表達式時發生錯誤。使用format_error/1
將三元素元組轉換為錯誤的英文描述。
Filename
的編碼可以透過註解來設定,如 epp
中所述。
-spec sendfile(Filename, Socket) -> {ok, non_neg_integer()} | {error, inet:posix() | closed | badarg | not_owner} when Filename :: name_all(), Socket :: inet:socket() | socket:socket() | fun((iolist()) -> ok | {error, inet:posix() | closed}).
將檔案 Filename
發送到 Socket
。如果成功,返回 {ok, BytesSent}
,否則返回 {error, Reason}
。
-spec sendfile(RawFile, Socket, Offset, Bytes, Opts) -> {ok, non_neg_integer()} | {error, inet:posix() | closed | badarg | not_owner} when RawFile :: fd(), Socket :: inet:socket() | socket:socket() | fun((iolist()) -> ok | {error, inet:posix() | closed}), Offset :: non_neg_integer(), Bytes :: non_neg_integer(), Opts :: [sendfile_option()].
從 RawFile
參照的檔案中,從 Offset
開始,將 Bytes
發送到 Socket
。如果成功,返回 {ok, BytesSent}
,否則返回 {error, Reason}
。如果 Bytes
設定為 0
,則會發送指定 Offset
後的所有資料。
使用的檔案必須使用 raw
標誌開啟,且呼叫 sendfile
的程序必須是 socket 的控制程序。請參閱 gen_tcp:controlling_process/2
或模組 socket
的 層級 otp
socket 選項 controlling_process
。
如果使用的作業系統不支援非阻塞 sendfile
,則會使用 Erlang 回退,使用 read/2
和 gen_tcp:send/2
。
選項列表可以包含以下選項
chunk_size
- Erlang 回退用於傳送資料的區塊大小。如果使用回退,請將此值設定為適合系統記憶體的值。預設值為 20 MB。
-spec set_cwd(Dir) -> ok | {error, Reason} when Dir :: name() | EncodedBinary, EncodedBinary :: binary(), Reason :: posix() | badarg | no_translation.
將檔案伺服器的目前工作目錄設定為 Dir
。如果成功,返回 ok
。
模組 file
中的函數通常將二進制檔視為原始檔名,也就是說,即使二進制的編碼與 native_name_encoding()
不一致,也會「按原樣」傳遞它們。但是,此函數期望二進制根據 native_name_encoding/0
返回的值進行編碼。
典型的錯誤原因如下
enoent
- 目錄不存在。enotdir
-Dir
的元件不是目錄。在某些平台上,會返回enoent
。eacces
- 缺少目錄或其其中一個父目錄的權限。badarg
-Dir
具有不正確的類型,例如元組。no_translation
-Dir
是以 ISO-latin-1 編碼字元的binary/0
,且 VM 使用 Unicode 檔名編碼運作。
警告
在未來的版本中,參數
Dir
的錯誤類型可能會產生例外狀況。
-spec sync(IoDevice) -> ok | {error, Reason} when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.
確保作業系統 (而不是 Erlang 執行階段系統) 保留的任何緩衝區都寫入到磁碟中。在某些平台上,此函式可能沒有任何作用。
典型的錯誤原因是
enospc
- 沒有足夠的空間來寫入檔案。
-spec truncate(IoDevice) -> ok | {error, Reason} when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.
在目前位置截斷 IoDevice
參照的檔案。如果成功,返回 ok
,否則返回 {error, Reason}
。
-spec write(IoDevice, Bytes) -> ok | {error, Reason} when IoDevice :: io_device() | io:device(), Bytes :: iodata(), Reason :: posix() | badarg | terminated.
將 Bytes
寫入到 IoDevice
參照的檔案中。此函式是唯一可以寫入以 raw
模式開啟的檔案的方式 (雖然它也適用於正常開啟的檔案)。如果成功,返回 ok
,否則返回 {error, Reason}
。
如果檔案開啟時 encoding
設定為 latin1
以外的值,則寫入的每個位元組可能會導致多個位元組寫入檔案,因為位元組範圍 0..255 可以表示一到四個位元組,具體取決於值和 UTF 編碼類型。如果要將 unicode:chardata/0
寫入 IoDevice
,則應改用 io:put_chars/2
。
典型的錯誤原因
ebadf
- 檔案並非開啟用於寫入。enospc
- 裝置上沒有剩餘空間。
-spec write_file(Filename, Bytes) -> ok | {error, Reason} when Filename :: name_all(), Bytes :: iodata(), Reason :: posix() | badarg | terminated | system_limit.
將 iodata
詞彙 Bytes
的內容寫入到檔案 Filename
。如果檔案不存在,則會建立檔案。如果檔案存在,則會覆寫先前的內容。如果成功,返回 ok
,否則返回 {error, Reason}
。
典型的錯誤原因
enoent
- 檔案名稱的元件不存在。enotdir
- 檔名的元件不是目錄。在某些平台上,會改為回傳enoent
。enospc
- 裝置上沒有剩餘空間。eacces
- 缺少寫入檔案或搜尋其中一個父目錄的權限。eisdir
- 指定的檔案是目錄。
-spec write_file(Filename, Bytes, Modes) -> ok | {error, Reason} when Filename :: name_all(), Bytes :: iodata(), Modes :: [mode()], Reason :: posix() | badarg | terminated | system_limit.
與 write_file/2
相同,但會採用第三個引數 Modes
,一個可能模式的列表,請參閱 open/2
。模式標記 binary
和 write
是隱含的,因此不應使用它們。
-spec write_file_info(Filename, FileInfo, Opts) -> ok | {error, Reason} when Filename :: name_all(), Opts :: [file_info_option()], FileInfo :: file_info(), Reason :: posix() | badarg.
變更檔案資訊。如果成功,返回 ok
,否則返回 {error, Reason}
。
FileInfo
是一個記錄 file_info
,定義在 Kernel 包含檔案 file.hrl
中。在呼叫此函數的模組中包含以下指令
-include_lib("kernel/include/file.hrl").
atime
、mtime
和 ctime
中設定的時間類型取決於 Opts :: {time, Type}
中設定的時間類型,如下所示
local
- 將設定的時間解釋為本地時間。universal
- 將其解釋為通用時間。posix
- 必須是自 Unix 時間紀元(即 1970-01-01 00:00 UTC)以來的秒數或之前的秒數。
預設值為 {time, local}
。
如果設定 raw
選項,則不會呼叫檔案伺服器,只會傳回關於本機檔案的資訊。
如果記錄中有指定以下欄位,則會使用它們:
atime =
date_time/0
|
non_neg_integer/0
- 上次讀取檔案的時間。mtime =
date_time/0
|
non_neg_integer/0
- 上次寫入檔案的時間。ctime =
date_time/0
|
non_neg_integer/0
- 在 Unix 系統上,此欄位指定的任何值都會被忽略(檔案的 "ctime" 會設定為目前時間)。在 Windows 系統上,此欄位是檔案要設定的新建立時間。mode =
non_neg_integer/0
- 檔案權限,為以下位元值的總和8#00400
- 讀取權限:擁有者8#00200
- 寫入權限:擁有者8#00100
- 執行權限:擁有者8#00040
- 讀取權限:群組8#00020
- 寫入權限:群組8#00010
- 執行權限:群組8#00004
- 讀取權限:其他8#00002
- 寫入權限:其他8#00001
- 執行權限:其他16#800
- 執行時設定使用者 ID16#400
- 執行時設定群組 ID
在 Unix 平台上,可能會設定除了上述列出的其他位元。
uid =
non_neg_integer/0
- 指示檔案擁有者。在非 Unix 檔案系統中會被忽略。gid =
non_neg_integer/0
- 給出檔案擁有者所屬的群組。在非 Unix 檔案系統中會被忽略。
典型的錯誤原因
eacces
- 缺少檔案的其中一個父目錄的搜尋權限。enoent
- 檔案不存在。enotdir
- 檔名的元件不是目錄。在某些平台上,會改為回傳enoent
。