在具備線程支持的操做系統上,可讓文件操做以其本身的線程執行,從而容許其餘Erlang進程與文件操做並行地繼續執行。在ERL(1)查看命令行標記 +A。
Erlang虛擬機在必定程度上支持Unicode的文件名。根據VM的啓動方式(使用參數 + fnu或+ fnl),給定的文件名能夠包含大於255的字符,VM系統會將文件名來回轉換爲本地文件名編碼。
Unicode字符轉換的默認行爲取決於底層操做系統/文件系統強制執行一致命名的程度。在確保全部文件名都採用一種或另外一種編碼的操做系統上,Unicode是默認值(目前這適用於Windows和MacOSX)。在具備徹底透明文件命名的操做系統上(即除MacOSX之外的全部Unix),ISO-latin-1文件命名是默認的。ISO-latin-1默認的緣由是文件名不能保證能夠根據預期的Unicode編碼進行解釋(即UTF-8),而且不能解碼的文件名只能經過使用「raw文件名「,其餘文件名稱爲二進制文件。
因爲文件名一般不是Erlang中的二進制文件,所以須要轉換須要處理原始文件名的應用程序,這就是爲何文件名的Unicode模式在具備徹底透明文件命名的系統上不是默認值。
原始文件名是OTP R14B01中的一項新功能,它容許用戶將徹底未解釋的文件名提供給底層操做系統/文件系統。它們以二進制文件形式提供,用戶能夠根據環境提供正確的編碼。函數file:native_name_encoding()可用於檢查虛擬機正在工做的編碼。若是該函數返回latin1文件名不會以任何方式轉換爲Unicode,若是它是utf8,若是原始文件名要遵循VM的約定(一般也是OS的約定),則應將其編碼爲UTF-8。若是您的文件系統具備不一致的文件命名,則使用原始文件名很是有用,其中一些文件以UTF-8編碼命名,而其餘文件則不以此命名。當虛擬機處於Unicode文件名模式時,這種混合文件名系統上file:list_dir可能會將文件名做爲原始二進制文件返回,由於它們不能被解釋爲Unicode文件名。即便虛擬機未以Unicode文件名翻譯模式啓動,原始文件名也可用於提供UTF-8編碼的文件名。
請注意,在Windows上,即便在Windows上,file:native_name_encoding()也會在默認狀況下返回utf8,即便在Windows上也是原始文件名的格式,但底層操做系統特定的代碼在小尾數UTF16的限制版本中工做。就Erlang程序員而言,Windows原生Unicode格式是UTF-8 ...
若是VM處於Unicode文件名模式,string()和char() 容許大於255. RawFilename是不受Unicode轉換影響的文件名,這意味着它能夠包含不符合文件系統指望的Unicode編碼的字符儘管虛擬機在Unicode文件名模式下啓動,可是不支持UTF-8字符)。
file_info() =
#file_info{size = undefined | integer() >= 0,
type = undefined
| device
| directory
| other
| regular
| symlink,
access = undefined
| read
| write
| read_write
| none,
atime = undefined
| file:date_time()
| integer() >= 0,
mtime = undefined
| file:date_time()
| integer() >= 0,
ctime = undefined
| file:date_time()
| integer() >= 0,
mode = undefined | integer() >= 0,
links = undefined | integer() >= 0,
major_device = undefined | integer() >= 0,
minor_device = undefined | integer() >= 0,
inode = undefined | integer() >= 0,
uid = undefined | integer() >= 0,
gid = undefined | integer() >= 0}
location() = integer()
| {bof, Offset :: integer()}
| {cur, Offset :: integer()}
| {eof, Offset :: integer()}
| bof
| cur
| eof
mode() = read
| write
| append
| exclusive
| raw
| binary
| {delayed_write,
Size :: integer() >= 0,
Delay :: integer() >= 0}
| delayed_write
| {read_ahead, Size :: integer() >= 1}
| read_ahead
| compressed
| {encoding, unicode:encoding()}
file_info_option() = {time, local} | {time, universal} | {time, posix}
導出
advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason}
Types:
IoDevice = io_device()
Offset = Length = integer()
Advise = posix_file_advise()
Reason = posix() | badarg
posix_file_advise() = normal
| sequential
| random
| no_reuse
| will_need
| dont_need
advise/4可用於宣佈未來以特定模式訪問文件數據的意圖,從而容許操做系統執行適當的優化。
在某些平臺上,此功能可能不起做用。
allocate(File, Offset, Length) -> ok | {error, posix()}
Types:
File = io_device()
Offset = Length = integer() >= 0
allocate/3可用於爲文件預分配空間。
此功能僅在實現此功能的平臺上成功。成功時,爲文件預分配空間,但文件大小可能不會更新。這種行爲取決於預分配實現。爲了保證文件大小更新,必須將文件截斷爲新的大小。
change_group(Filename, Gid) -> ok | {error, Reason}
Types:
Filename = name_all()
Gid = integer()
Reason = posix() | badarg
更改文件組。請參閱 write_file_info/2。
change_mode(Filename, Mode) -> ok | {error, Reason}
Types:
Filename = name_all()
Mode = integer()
Reason = posix() | badarg
更改文件的權限。請參閱 write_file_info/2。
change_owner(Filename, Uid) -> ok | {error, Reason}
Types:
Filename = name_all()
Uid = integer()
Reason = posix() | badarg
更改文件的全部者和組。請參閱 write_file_info/2。
change_time(Filename, Mtime) -> ok | {error, Reason}
Types:
Filename = name_all()
Mtime = date_time()
Reason = posix() | badarg
更改文件的修改和訪問時間。請參閱 write_file_info/2。
close(IoDevice) -> ok | {error, Reason}
Types:
IoDevice = io_device()
Reason = posix() | badarg | terminated
關閉IoDevice引用的文件。它一般會返回正常,預計會出現諸如內存不足等嚴重錯誤。
請注意,若是在打開文件時使用了選項delayed_write,則close/1可能會返回舊的寫入錯誤,甚至不會嘗試關閉該文件。見open/2。
consult(Filename) -> {ok, Terms} | {error, Reason}
Types:
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}]}
文件名的編碼能夠經過epp(3)中描述的註釋來設置。
copy(Source, Destination) -> {ok, BytesCopied} | {error, Reason}
copy(Source, Destination, ByteCount) -> {ok, BytesCopied} | {error, Reason}
Types:
Source = Destination = io_device() | Filename | {Filename, Modes}
Filename = name_all()
Modes = [mode()]
ByteCount = integer() >= 0 | infinity
BytesCopied = integer() >= 0
Reason = posix() | badarg | terminated
從Source到Destination複製ByteCount字節 。
Source和Destination是指來自例如open/2的文件名或IO設備。 ByteCount默認爲infinity,表示無限數量的字節。
Modes模式是可能模式的列表,請參閱open/2,默認爲[]。
若是Source和 Destination都指向文件名,那麼這些文件分別以[read,binary] 和[write,binary]做爲模式列表的預先打開,以優化副本。
若是Source引用一個文件名,則在拷貝以前以讀取模式打開,並在完成時關閉。
若是Destination指向一個文件名,它會在複製以前以模式列表預先以寫入模式打開,並在完成時關閉。
返回{ok,BytesCopied},其中BytesCopied是實際複製的字節數,若是在源上遇到文件結尾,則可能小於ByteCount。若是操做失敗, 則返回{error,Reason}。
典型的錯誤緣由:至於open/2,若是一個文件必須打開,以及read/2和write/2。
del_dir(Dir) -> ok | {error, Reason}
Types:
Dir = name_all()
Reason = posix() | badarg
嘗試刪除目錄Dir。該目錄在被刪除以前必須是空的。成功返回ok。
典型的錯誤緣由是:
eacces
Dir的父目錄缺乏搜索或寫入權限。
eexist
該目錄不是空的。
enoent
該目錄不存在。
enodir
Dir的一個組件不是一個目錄。在某些平臺上,取而代之的是返回enoent。
einval
嘗試刪除當前目錄。在某些平臺上,eacces被返回。
delete(Filename) -> ok | {error, Reason}
Types:
Filename = name_all()
Reason = posix() | badarg
試圖刪除文件Filename。成功返回ok。
典型的錯誤緣由是:
enoent
該文件不存在。
eacces
對該文件或其父母之一缺乏權限。
eperm
該文件是一個目錄,用戶不是超級用戶。
enotdir
文件名的一個組件不是一個目錄。在某些平臺上,取而代之的是返回enoent。
einval
文件名具備不正確的類型,例如元組。
警告
在將來的版本中,Filename參數的錯誤類型 可能會生成異常。
eval(Filename) -> ok | {error, Reason}
Types:
Filename = name_all()
Reason = posix()
| badarg
| terminated
| system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}
讀取和運算由'.'分隔的Erlang表達式(或',',一系列表達式也是一個表達式),來自 Filename。運算的實際結果不返回;文件中的任何表達式序列都必須存在,由於它的反作用。返回如下內容之一:
ok
該文件被讀取和運算。
{error,atom()}
打開文件或讀取文件時發生錯誤。有關典型錯誤代碼的列表,請參閱open/2。
{error,{Line,Mod,Term}}
解釋文件中的Erlang表達式時發生錯誤。使用format_error/1將三元素元組轉換爲錯誤的英文描述。
文件名的編碼能夠經過epp(3)中描述的註釋來設置。
eval(Filename, Bindings) -> ok | {error, Reason}
Types:
Filename = name_all()
Bindings = erl_eval:binding_struct()
Reason = posix()
| badarg
| terminated
| system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}
與eval/1相同,但變量綁定 Bindings用於運算。請參閱 erl_eval(3)關於變量綁定。
file_info(Filename) -> {ok, FileInfo} | {error, Reason}
Types:
Filename = name_all()
FileInfo = file_info()
Reason = posix() | badarg
此功能已過期。 改成使用read_file_info/1,2。
format_error(Reason) -> Chars
Types:
Reason = posix()
| badarg
| terminated
| system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}
Chars = string()
鑑於此模塊中任何函數返回的錯誤緣由,請返回英文錯誤的描述性字符串。
get_cwd() -> {ok, Dir} | {error, Reason}
Types:
Dir = filename()
Reason = posix()
返回{ok,Dir},其中Dir 是文件服務器的當前工做目錄。
注意
在極少數狀況下,這個函數可能在Unix上失敗。若是當前目錄的父目錄不存在讀取權限,則可能發生這種狀況。
典型的錯誤緣由是:
eacces
缺乏當前目錄的其中一個父項的讀取權限。
get_cwd(Drive) -> {ok, Dir} | {error, Reason}
Types:
Drive = string()
Dir = filename()
Reason = posix() | badarg
驅動器的格式應爲「 Letter:」,例如「c:」。返回{ok,Dir}或 {error,Reason},其中Dir 是指定驅動器的當前工做目錄。
該函數在沒有當前驅動器概念的平臺(例如Unix)上返回{error,enotsup}。
典型的錯誤緣由是:
enotsup
操做系統沒有驅動器的概念。
eacces
該驅動器不存在。
einval
雲端硬盤的格式無效。
list_dir(Dir) -> {ok, Filenames} | {error, Reason}
Types:
Dir = name_all()
Filenames = [filename()]
Reason = posix()
| badarg
| {no_translation, Filename :: unicode:latin1_binary()}
列出目錄中的全部文件,但具備「原始」名稱的文件除外。若是成功,返回 {ok,Filenames}。不然,它返回{error,Reason}。 文件名是目錄中全部文件名稱的列表。名稱沒有排序。
典型的錯誤緣由是:
eacces
Dir或其父目錄之一缺乏搜索或寫入權限。
enoent
該目錄不存在。
{no_translation,Filename}
Filename是一個二進制,其字符在ISO-latin-1中編碼,VM以參數+ fnue啓動。
list_dir_all(Dir) -> {ok, Filenames} | {error, Reason}
Types:
Dir = name_all()
Filenames = [filename_all()]
Reason = posix() | badarg
列出目錄中的全部文件,包括具備「原始」名稱的文件。若是成功,返回{ok,Filenames}。不然,它返回{error,Reason}。 文件名是目錄中全部文件名稱的列表。名稱沒有排序。
典型的錯誤緣由是:
eacces
Dir或其父目錄之一缺乏搜索或寫入權限。
enoent
該目錄不存在。
make_dir(Dir) -> ok | {error, Reason}
Types:
Dir = name_all()
Reason = posix() | badarg
嘗試建立目錄Dir。缺乏父目錄不能建立。成功返回ok。
典型的錯誤緣由是:
eacces
Dir的父目錄缺乏搜索或寫入權限。
eexist
已經有一個名爲Dir的文件或目錄。
enoent
Dir的一個組件不存在。
enospc
設備上沒有剩餘空間。
enotdir
Dir的一個組件不是一個目錄。在某些平臺上,取而代之的是返回enoent。
make_link(Existing, New) -> ok | {error, Reason}
Types:
Existing = New = name_all()
Reason = posix() | badarg
在支持連接的平臺(Unix和Windows)上創建從Existing到 New的硬連接。若是連接成功建立,該函數返回ok,或 {error,Reason}。在不支持連接的平臺上,返回{error,enotsup}。
典型的錯誤緣由:
eacces
缺乏Existing或 New的父目錄的讀取或寫入權限。
eexist
新已經存在。
enosup
該平臺不支持硬連接。
make_symlink(Existing, New) -> ok | {error, Reason}
Types:
Existing = New = name_all()
Reason = posix() | badarg
在支持符號連接(大多數Unix系統和Windows以Vista開頭)的平臺上,該函數建立一個文件或目錄Existing的新符號連接。 Existing須要不存在。若是連接成功建立,該函數返回ok,或{error,Reason}。在不支持符號連接的平臺上, 返回{error,enotsup}。
典型的錯誤緣由:
eacces
缺乏Existing或New的父目錄的讀取或寫入權限。
eexist
新已經存在。
enotsup
此平臺不支持符號連接。
native_name_encoding() -> latin1 | utf8
此函數返回配置的默認文件名編碼以用於原始文件名。一般,提供文件名raw(做爲二進制文件)的應用程序應該服從由該函數返回的字符編碼。
默認狀況下,VM在文件系統和/或使用徹底透明文件命名的操做系統上使用ISO-latin-1文件名編碼。這包括除MacOSX以外的全部Unix版本,其中vfs層強制執行UTF-8文件命名。經過在啓動Erlang時給出實驗選項+ fnu,即便對於那些系統,也能夠打開文件名的UTF-8轉換。若是Unicode文件名翻譯生效,只要文件名符合編碼,系統就會照常運行,但會返回未正確編碼爲UTF-8的文件名做爲原始文件名(即二進制文件)。
在Windows上,該函數默認返回utf8。操做系統使用純粹的Unicode命名方案,文件名老是能夠解釋爲有效的Unicode。底層Windows操做系統實際上使用小尾數UTF-16編碼文件名的事實能夠被Erlang程序員忽略。Windows和MacOSX是虛擬機默認以Unicode文件名模式運行的惟一操做系統。
open(File, Modes) -> {ok, IoDevice} | {error, Reason}
Types:
File = Filename | iodata()
Filename = name_all()
Modes = [mode() | ram]
IoDevice = io_device()
Reason = posix() | badarg | system_limit
以由Modes肯定的模式打開文件File,該模式可能包含如下一項或多項內容:
read
該文件必須存在,已打開供閱讀。
write
該文件被打開寫入。若是它不存在,則建立它。若是該文件存在,而且若是寫入未與讀取結合,則該文件將被截斷。
append
該文件將被打開進行寫入,而且若是該文件不存在,該文件將被建立。對使用append打開的文件的每一個寫入操做都將在文件末尾進行。
exclusive
若是該文件在寫入時打開,則該文件若是不存在則建立。若是文件存在,打開將返回 {error,eexist}。
警告
此選項不保證在不支持O_EXCL的文件系統上的排他性,例如NFS。除非您知道文件系統支持該選項,不然不要依賴此選項(一般,本地文件系統應該是安全的)。
raw
該raw選項容許一個文件更快的訪問,由於不須要Erlang進程來處理文件。可是,以這種方式打開的文件具備如下限制:
io模塊中的功能沒法使用,由於它們只能與Erlang進程通訊。相反,使用read/2,read_line/1和 write/2 函數。
特別是若是要在原始文件上使用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
與{Delay_write,Size,Delay}相同,使用Size和 Delay的合理默認值。(大約64 KB,2秒)
{read_ahead, Size}
該選項激活讀取數據緩衝。若是 read/2調用的字節數大大小於Size字節,則對操做系統的讀取操做仍會針對Size 字節塊執行。額外的數據被緩衝並在隨後的read/2調用中返回,從而減小操做系統調用次數,從而提升性能。
所述read_ahead緩衝器也是高度由利用read_line/1在功能原始模式下,爲何建議該選項(出於性能緣由)使用該函數訪問原始文件時。
若是read/2調用的大小不小於或大於size字節,則不會得到性能增益。
read_ahead
同爲{read_ahead,Size}有一個合理的默認值大小。(大約64 KB)
compressed
使讀取或寫入gzip壓縮文件成爲可能。該壓縮選項必須以組合讀或寫,但不能同時使用。請注意,使用read_file_info/1獲取的文件大小 極可能與可從壓縮文件讀取的字節數不匹配。
{encoding, Encoding}
使文件自動轉換特定(Unicode)編碼中的字符。請注意,提供給file:write或由file:read返回的數據仍然是面向字節的,該選項僅表示數據實際存儲在磁盤文件中的方式。
根據編碼的不一樣,讀取和寫入數據的方法是首選。latin1的默認編碼意味着使用這個(文件)模塊讀取和寫入數據,由於這裏提供的接口使用面向字節的數據,而使用其餘(Unicode)編碼使得io(3)模塊的get_chars,get_line和put_chars功能更適合,由於它們可使用完整的Unicode範圍。
若是數據以沒法轉換爲指定編碼的格式發送到io_device(),或者數據是以沒法應對數據字符範圍的格式返回數據的函數讀取的,則會發生錯誤,而且該文件將被關閉。
編碼的容許值是:
LATIN1
默認編碼。提供給ie file:write的字節按原樣寫入文件,一樣從文件讀取的字節返回到ie file:read。若是使用io(3)模塊進行寫入,則該文件只能處理直至代碼點255(ISO-latin-1範圍)的Unicode字符。
unicode或utf8
在寫入文件或從文件中讀取字符以前,字符會轉換爲UTF-8編碼或從UTF-8編碼轉換而來。只要沒有存儲在文件中的數據超出ISO-latin-1範圍(0..255),以這種方式打開的文件就可使用file:read函數讀取,但若是數據包含Unicode超出該範圍的碼點。該文件最好使用支持Unicode的io(3)模塊中的函數進行讀取 。
在實際存儲到磁盤文件以前,經過任何方式寫入文件的字節都會轉換爲UTF-8編碼。
utf16或{utf16,big}
像unicode同樣工做,可是能夠在大端的UTF-16而不是UTF-8上進行翻譯。
{UTF16,little}
像unicode同樣工做,但翻譯是經過小端UTF-16而不是UTF-8完成的。
utf32或{utf32,big}
像unicode同樣工做,可是能夠在大端的UTF-32而不是UTF-8上進行翻譯。
{UTF32,little}
像unicode同樣工做,可是可使用小端UTF-32而不是UTF-8進行翻譯。
編碼能夠經過使用io:setopts/2函數爲「即時」文件進行更改,爲何可使用latin1編碼對文件進行分析,例如BOM,位於BOM以後,而後設置爲正確的編碼進一步閱讀。參見unicode(3)模塊瞭解BOM的功能。
原始文件不容許使用此選項。
ram
文件必須是iodata()。返回一個fd(),它使文件模塊對內存中的數據進行操做,就像它是一個文件同樣。
返回:
{ok,IoDevice}
該文件已在請求的模式下打開。 IoDevice是對該文件的引用。
{error, Reason}
該文件沒法打開。
IoDevice其實是處理文件的過程的pid。這個過程與最初打開文件的過程相關聯。若是IoDevice連接的任何進程終止,則文件將被關閉,進程自己將被終止。今後調用返回的IoDevice可用做IO函數的參數(請參閱 io(3))。
注意
在之前版本的文件,模式都給出一個原子read,write,或read_write,而不是一個列表。出於向後兼容的緣由,這仍然是容許的,但不該該用於新代碼。另請注意,模式列表中不容許使用read_write。
典型的錯誤緣由:
enoent
該文件不存在。
eacces
缺乏權限讀取文件或搜索其中一個父目錄。
eisdir
指定的文件不是常規文件。它多是一個目錄,一個fifo或一個設備。
enotdir
文件名的一個組件不是一個目錄。在某些平臺上,取而代之的是返回enoent。
enospc
設備上沒有剩餘空間(若是 指定了寫訪問權限)。
path_consult(Path, Filename) -> {ok, Terms, FullName} | {error, Reason}
Types:
Path = [Dir]
Dir = Filename = name_all()
Terms = [term()]
FullName = filename_all()
Reason = posix()
| badarg
| terminated
| system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}
搜索路徑Path(目錄名稱列表),直到找到文件Filename。若是文件名是絕對文件名,則路徑被忽略。而後從文件中讀取用'.'分隔的Erlang項。返回如下內容之一:
{ok,Terms,FullName}
該文件已成功讀取。FullName是文件的全名。
{error,enoent}
該文件沒法在Path中的任何目錄中找到 。
{error,atom()}
打開文件或讀取文件時發生錯誤。有關典型錯誤代碼的列表,請參閱open/2。
{error,{Line,Mod,Term}}
解釋文件中的Erlang項時發生錯誤。使用format_error/1將三元素元組轉換爲錯誤的英文描述。
文件名的編碼能夠經過epp(3)中描述的註釋來設置。
path_eval(Path, Filename) -> {ok, FullName} | {error, Reason}
Types:
Path = [Dir :: name_all()]
Filename = name_all()
FullName = filename_all()
Reason = posix()
| badarg
| terminated
| system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}
搜索路徑Path(目錄名稱列表),直到找到文件Filename。若是文件名是絕對文件名,則路徑被忽略。而後讀取並運算由'.'分隔的Erlang表達式。(或',',表達式序列也是一個表達式)。運算的實際結果不返回;文件中的任何表達式序列都必須存在,由於它的反作用。返回如下內容之一:
{ok,FullName}
該文件被讀取和運算。FullName是文件的全名。
{error,enoent}
該文件沒法在Path中的任何目錄中找到 。
{error,atom()}
打開文件或讀取文件時發生錯誤。有關典型錯誤代碼的列表,請參閱open/2。
{error,{Line,Mod,Term}}
解釋文件中的Erlang表達式時發生錯誤。使用format_error/1將三元素元組轉換爲錯誤的英文描述。
文件名的編碼能夠經過epp(3)中描述的註釋來設置。
path_open(Path, Filename, Modes) -> {ok, IoDevice, FullName} | {error, Reason}
Types:
Path = [Dir :: name_all()]
Filename = name_all()
Modes = [mode()]
IoDevice = io_device()
FullName = filename_all()
Reason = posix() | badarg | system_limit
搜索路徑Path(目錄名稱列表),直到找到文件Filename。若是文件名是絕對文件名,則路徑被忽略。而後以Modes肯定的模式打開文件。返回如下內容之一:
{ok,IoDevice,FullName}
該文件已在請求的模式下打開。 IoDevice是對文件的引用,FullName是文件的全名。
{錯誤,enoent}
該文件沒法在Path中的任何目錄中找到 。
{error,atom()}
該文件沒法打開。
path_script(Path, Filename) -> {ok, Value, FullName} | {error, Reason}
Types:
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。若是文件名是絕對文件名,則路徑被忽略。而後讀取並運算由'.'分隔的Erlang表達式。(或',',表達式序列也是一個表達式)。返回如下內容之一:
{ok,Value,FullName}
該文件被讀取和運算。全名是文件的全名值的最後一個表達式的值。
{error,enoent}
該文件沒法在Path中的任何目錄中找到 。
{error,atom()}
打開文件或讀取文件時發生錯誤。有關典型錯誤代碼的列表,請參閱open/2。
{error,{Line,Mod,Term}}
解釋文件中的Erlang表達式時發生錯誤。使用format_error/1將三元素元組轉換爲錯誤的英文描述。
文件名的編碼能夠經過epp(3)中描述的註釋來設置。
path_script(Path, Filename) -> {ok, Value, FullName} | {error, Reason}
Types:
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。若是文件名是絕對文件名,則路徑被忽略。而後讀取並運算由'.'分隔的Erlang表達式。(或',',表達式序列也是一個表達式)。返回如下內容之一:
{ok,Value,FullName}
該文件被讀取和運算。全名是文件的全名值的最後一個表達式的值。
{error,enoent}
該文件沒法在Path中的任何目錄中找到 。
{error,atom()}
打開文件或讀取文件時發生錯誤。有關典型錯誤代碼的列表,請參閱open / 2。
{error,{Line,Mod,Term}}
解釋文件中的Erlang表達式時發生錯誤。使用format_error/1將三元素元組轉換爲錯誤的英文描述。
文件名的編碼能夠經過epp(3)中描述的註釋來設置。
path_script(Path, Filename, Bindings) -> {ok, Value, FullName} | {error, Reason}
Types:
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(3)關於變量綁定。
pid2name(Pid) -> {ok, Filename} | undefined
Types:
Filename = filename_all()
Pid = pid()
若是Pid是IO設備,即從open/2返回的pid,則此函數返回文件名,或者更確切地說:
{ok,Filename}
若是此節點的文件服務器不是從屬節點,則該節點的文件服務器將打開文件(這意味着 Pid必須是本地pid),而且該文件未關閉。文件名是字符串格式的文件名。
undefined
在全部其餘狀況下。
警告
該功能僅用於調試。
position(IoDevice, Location) -> {ok, NewPosition} | {error, Reason}
Types:
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 相同。
請注意,偏移量以字節計,而不是字符。若是使用除latin1以外的其餘編碼打開文件,則一個字節不對應一個字符。在這樣的文件中定位只能經過已知的字符邊界完成,也就是說,經過獲取當前位置,到文件的開始/結尾或其餘某些已知位於正確字符邊界的位置(一般超出文件中的字節順序標記,它具備已知的字節大小)。
典型的錯誤緣由是:
einval
不管是位置是非法的,或在文件中其偏移量計算爲負。請注意,若是結果位置爲負值,則結果爲錯誤,而且在調用後文件位置未定義。
pread(IoDevice, LocNums) -> {ok, DataL} | eof | {error, Reason}
Types:
IoDevice = io_device()
LocNums = [{Location :: location(), Number :: integer() >= 0}]
DataL = [Data]
Data = string() | binary() | eof
Reason = posix() | badarg | terminated
在一次操做中執行pread/3的序列,這比一次調用它們更有效。返回{ok,[Data,...]}或 {error,Reason},其中每一個Data(相應的pread的結果 )能夠是列表或二進制文件,具體取決於文件的模式,或者eof,若是請求位置超出了文件結尾。
因爲位置是以字節偏移量給出的,所以在處理編碼設置爲latin1之外的文件時必須特別當心,由於並不是每一個字節位置都是此類文件上的有效字符邊界。
pread(IoDevice, Location, Number) -> {ok, Data} | eof | {error, Reason}
Types:
IoDevice = io_device()
Location = location()
Number = integer() >= 0
Data = string() | binary()
Reason = posix() | badarg | terminated
在一次操做中合併position/2和read/2,這比一次調用它們更有效。若是IoDevice已在原始模式下打開,則會有一些限制:位置只容許爲整數; 操做後,文件的當前位置未定義。
因爲位置是以字節偏移量給出的,所以在處理編碼設置爲latin1之外的文件時必須特別當心,由於並不是每一個字節位置都是此類文件上的有效字符邊界。
pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}}
Types:
IoDevice = io_device()
LocBytes = [{Location :: location(), Bytes :: iodata()}]
N = integer() >= 0
Reason = posix() | badarg | terminated
在一次操做中執行一系列pwrite/3,這比一次調用一個更有效。返回ok或{error,{N,Reason}},其中 N是在失敗以前完成的成功寫入次數。
當使用除latin1以外的其餘編碼定位文件時,必須注意將位置設置在正確的字符邊界上,詳情請參閱position/2。
read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason}
Types:
IoDevice = io_device() | atom()
Number = integer() >= 0
Data = string() | binary()
Reason = posix()
| badarg
| terminated
| {no_translation, unicode, latin1}
從IoDevice引用的文件讀取Number字節/字符。read/2,pread/3 和read_line/1函數是從原始模式打開的文件讀取的惟一方法(儘管它們也適用於一般打開的文件)。
對於編碼設置爲latin1之外的文件,文件中的一個字符可能由多個字節表示。參數Number始終表示從文件中讀取的字符數,爲何在讀取Unicode文件時文件中的位置可能比此數字移動得多。
另外,若是編碼設置爲latin1之外的其餘值,若是數據包含大於255的字符,則read/3調用將失敗,爲何讀取此類文件時首選io(3)模塊。
該函數返回:
{ok,Data}
若是文件以二進制模式打開,讀取的字節以二進制形式返回,不然以列表形式返回。若是文件結尾已達到,列表或二進制文件將短於請求的字節數。
eof
若是Number> 0和文件結尾已達到,則返回任何能夠讀取的內容。
典型的錯誤緣由:
ebadf
該文件未打開以供閱讀。
{no_translation,unicode,latin1}
該文件使用另外一種編碼而不是latin1打開,而且文件中的數據不能轉換爲該函數返回的字節數據。
read_file(Filename) -> {ok, Binary} | {error, Reason}
Types:
Filename = name_all()
Binary = binary()
Reason = posix() | badarg | terminated | system_limit
返回{ok,Binary},其中Binary是包含Filename的內容的二進制數據對象,或 {error,Reason}若是發生錯誤。
典型的錯誤緣由:
enoent
該文件不存在。
eacces
缺乏的權限讀取文件或者搜索其中一個父目錄。
eisdir
指定的文件是一個目錄。
enotdir
文件名的一個組件不是一個目錄。在某些平臺上,取而代之的是返回enoent。
enomem
文件內容沒有足夠的內存。
read_file_info(Filename) -> {ok, FileInfo} | {error, Reason}
read_file_info(Filename, Opts) -> {ok, FileInfo} | {error, Reason}
Types:
Filename = name_all()
Opts = [file_info_option()]
FileInfo = file_info()
Reason = posix() | badarg
檢索有關文件的信息。若是成功則返回 {ok,FileInfo},不然返回 {error,Reason}。FileInfo 是一個記錄 file_info,在內核包含文件file.hrl中定義 。在調用函數的模塊中包含如下指令:
-include_lib("kernel/include/file.hrl").
atime,mtime和ctime中返回的時間類型 取決於Opts::{time,Type}中設置的時間類型。類型local將返回本地時間,universal將返回通用時間,posix將返回自unix time epoch(1970-01-01 00:00 UTC)以前或以後的秒數。默認是{time,local}。
注意
因爲文件時間在大多數操做系統上以posix時間存儲,所以使用posix選項查詢文件信息會更快。
記錄file_info包含如下字段。
size = integer()> = 0
文件大小(以字節爲單位)
type = device | directory | other | regular | symlink
文件的類型。
access = read | write | read_write | none
當前系統訪問該文件。
atime = date_time() | integer()> = 0
上次讀取文件時。
mtime = date_time() | integer()> = 0
上次寫入文件的時間。
ctime = date_time() | integer()> = 0
這段時間的解釋取決於操做系統。在Unix上,它是最後一次更改文件或inode。在Windows中,這是建立時間。
mode = integer() >= 0
文件權限爲如下位值的總和:
8#00400
讀取權限:全部者
8#00200
寫權限:全部者
8#00100
執行權限:全部者
8#00040
讀權限:組
8#00020
寫入權限:組
8#00010
執行權限:組
8#00004
讀權限:其餘
8#00002
寫入權限:其餘
8#00001
執行權限:其餘
16#800
在執行時設置用戶ID
16#400
執行時設置組ID
在Unix平臺上,能夠設置除上面列出的位以外的其餘位。
links = integer()> = 0
文件連接的數量(對於沒有連接概念的文件系統,這老是1)。
major_device = integer()> = 0
標識文件所在的文件系統。在Windows中,數字表示一個驅動器,以下所示:0表示A :, 1表示B :,依此類推。
minor_device = integer()> = 0
只對Unix上的字符設備有效。在全部其餘狀況下,該字段爲零。
inode = integer()> = 0
給出inode編號。在非Unix文件系統上,此字段將爲零。
uid = integer()> = 0
表示文件的全部者。非Unix文件系統將爲零。
gid = integer()> = 0
給出文件全部者屬於的組。對於非Unix文件系統將爲零。
典型的錯誤緣由:
eacces
缺乏文件父目錄之一的搜索權限。
enoent
該文件不存在。
enotdir
文件名的一個組件不是一個目錄。在某些平臺上,取而代之的是返回enoent。
read_line(IoDevice) -> {ok, Data} | eof | {error, Reason}
Types:
IoDevice = io_device() | atom()
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的行。
該功能可用於以原始模式打開的文件。可是,若是未使用指定的{read_ahead,Size}選項打開文件,則在原始文件上使用它是低效的,這就是爲何在打開面向原始行讀取的文本文件時強烈建議組合raw和{read_ahead,Size}。
若是編碼設置爲latin1之外的其餘值,若是數據包含大於255的字符,則read_line/1調用將失敗,爲何讀取此類文件時首選io(3)模塊。
該函數返回:
{ok,Data}
返回文件中的一行,包括尾隨LF,但CRLF序列由單個LF替換(參見上文)。
若是文件以二進制模式打開,讀取的字節以二進制形式返回,不然以列表形式返回。
eof
若是在讀取任何內容以前已達到文件結尾,則返回。
{error, Reason}
發生錯誤。
典型的錯誤緣由:
ebadf
該文件未打開以供閱讀。
{no_translation,unicode,latin1}
該文件是使用除latin1以外的其餘編碼打開的,而且該文件上的數據沒法轉換爲此函數返回的面向字節的數據。
read_link(Name) -> {ok, Filename} | {error, Reason}
Types:
Name = name_all()
Filename = filename()
Reason = posix() | badarg
若是 Name引用不是「原始」文件名的符號連接,則返回{ok,Filename},不然返回{error,Reason} 。在不支持符號連接的平臺上,返回值將是{error,enotsup}。
典型的錯誤緣由:
einval
名稱不引用符號連接或引用的文件的名稱不符合預期的編碼。
enoent
該文件不存在。
enotsup
此平臺不支持符號連接。
read_link_all(Name) -> {ok, Filename} | {error, Reason}
Types:
Name = name_all()
Filename = filename_all()
Reason = posix() | badarg
若是Name引用符號連接 ,則返回{ok,Filename},不然 返回{ error,Reason}。在不支持符號連接的平臺上,返回值將是{error,enotsup}。
請注意,文件名能夠是列表或二進制文件。
典型的錯誤緣由:
einval
名稱不是指符號連接。
enoent
該文件不存在。
enotsup
此平臺不支持符號連接。
read_link_info(Name) -> {ok, FileInfo} | {error, Reason}
read_link_info(Name, Opts) -> {ok, FileInfo} | {error, Reason}
Types:
Name = name_all()
Opts = [file_info_option()]
FileInfo = file_info()
Reason = posix() | badarg
這個函數的做用相似於read_file_info/1,2,除了若是Name是一個符號連接,關於該連接的信息將在file_info記錄中返回而且該記錄的類型字段將被設置爲 符號連接。
若是Name不是符號連接,則此函數返回與read_file_info/1徹底相同的結果。在不支持符號連接的平臺上,此函數始終等效於read_file_info/1。
rename(Source, Destination) -> ok | {error, Reason}
Types:
Source = Destination = name_all()
Reason = posix() | badarg
嘗試將文件Source重命名爲Destination。它可用於在目錄之間移動文件(和目錄),但僅指定目標是不夠的。目標文件名也必須指定。例如,若是bar是普通文件,而foo和baz是目錄,則重命名(「foo / bar」,「baz」)會返回錯誤,但重命名(「foo / bar」,「baz / bar」)會成功。若是成功則返回ok。
注意
在大多數平臺上不容許重命名打開的文件(請參閱下面的eacces)。
典型的錯誤緣由:
eacces
缺乏源或目標的父目錄的讀或寫權限。在某些平臺上,若是Source或Destination處於打開狀態,則會出現此錯誤 。
eexist
目的地不是空目錄。在某些平臺上,當源和目標不是同一類型時也會給出。
einval
Source是根目錄,或者Destination是Source的子目錄。
eisdir
目的地是一個目錄,但Source不是。
enoent
來源不存在。
enotdir
Source是一個目錄,但Destination不是。
exdev
源和目標位於不一樣的文件系統上。
script(Filename) -> {ok, Value} | {error, Reason}
Types:
Filename = name_all()
Value = term()
Reason = posix()
| badarg
| terminated
| system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}
讀取和運算由'.'分隔的Erlang表達式。(或',',表達式序列也是表達式),來自文件。返回如下之一:
{ok,Value}
該文件被讀取和運算。值是最後一個表達式的值。
{error,atom()}
打開文件或讀取文件時發生錯誤。有關典型錯誤代碼的列表,請參見open/2。
{error,{Line,Mod,Term}}
解釋文件中的Erlang表達式時發生錯誤。使用format_error/1將三元素元組轉換爲錯誤的英文描述。
文件名的編碼能夠經過epp(3)中描述的註釋來設置。
script(Filename, Bindings) -> {ok, Value} | {error, Reason}
Types:
Filename = name_all()
Bindings = erl_eval:binding_struct()
Value = term()
Reason = posix()
| badarg
| terminated
| system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}
與script/1相同,但在運算中使用變量綁定Bindings。請參閱有關變量綁定的erl_eval(3)。
set_cwd(Dir) -> ok | {error, Reason}
Types:
Dir = name()
Reason = posix() | badarg | no_translation
將文件服務器的當前工做目錄設置爲Dir。若是成功則返回ok。
典型的錯誤緣由是:
enoent
該目錄不存在。
enotdir
Dir的一個組件不是一個目錄。在某些平臺上,返回enoent。
eacces
沒有目錄或其父目錄的權限。
badarg
Dir有一個不正確的類型,好比元組。
no_translation
Dir是一個二進制,其字符以ISO-latin-1編碼,VM以參數+ fnue開始。
警告
在將來的版本中,Dir 參數的錯誤類型可能會生成異常。
sync(IoDevice) -> ok | {error, Reason}
Types:
IoDevice = io_device()
Reason = posix() | badarg | terminated
確保操做系統(而不是Erlang運行時系統)保存的任何緩衝區都寫入磁盤。在某些平臺上,此功能可能不起做用。
典型的錯誤緣由是:
enospc
沒有足夠的空間來寫入文件。
datasync(IoDevice) -> ok | {error, Reason}
Types:
IoDevice = io_device()
Reason = posix() | badarg | terminated
確保操做系統(而不是Erlang運行時系統)保存的任何緩衝區都寫入磁盤。在許多方面,它相似於fsync,但不須要更新文件的某些元數據,如訪問時間。在某些平臺上,此功能可能不起做用。
訪問數據庫或日誌文件的應用程序一般會寫入一個小小的數據片斷(例如,日誌文件中的一行),而後當即調用fsync()以確保寫入的數據物理存儲在硬盤上。不幸的是,fsync()將始終啓動兩個寫操做:一個用於新寫入的數據,另外一個用於更新存儲在inode中的修改時間。若是修改時間不是事務概念的一部分,則可使用fdatasync()來避免沒必要要的inode磁盤寫入操做。
僅在某些POSIX系統中可用。此調用會致使在未實現fdatasync系統調用的系統中調用fsync()或無效。
truncate(IoDevice) -> ok | {error, Reason}
Types:
IoDevice = io_device()
Reason = posix() | badarg | terminated
截斷在當前位置由IoDevice引用的文件。若是成功則返回ok,不然{error,Reason}。
sendfile(Filename, Socket) -> {ok, integer() >= 0} | {error, inet:posix() | closed | badarg | not_owner}
Types:
Filename = name_all()
Socket = inet:socket()
將文件Filename發送到Socket。若是成功則返回{ok,BytesSent},不然返回{error,Reason}。
sendfile(RawFile, Socket, Offset, Bytes, Opts) ->
{ok, integer() >= 0} |
{error, inet:posix() | closed | badarg | not_owner}
Types:
RawFile = fd()
Socket = inet:socket()
Offset = Bytes = integer() >= 0
Opts = [sendfile_option()]
sendfile_option() = {chunk_size, integer() >= 0}
從偏移量開始,從RawFile引用的文件發送字節到套接字。若是成功則返回{ok,BytesSent},不然返回{error,Reason}。若是字節設置爲0,則發送給定偏移後的全部數據。
必須使用原始標誌打開使用的文件,而且調用sendfile的進程必須是套接字的控制進程。請參見gen_tcp:controlling_process/2
若是使用的操做系統不支持sendfile,則使用file:read和gen_tcp:send的Erlang fallback。
選項列表能夠包含如下選項:
chunk_size
erlang fallback用於發送數據的塊大小。若是使用fallback功能,則應將其設置爲適合系統內存的值。默認值是20 MB。
在具備線程支持的操做系統上,建議使用異步線程。看命令行標記 +A在ERL(1) 。若是沒法使用sendfile的異步線程,則建議爲套接字上的發送緩衝區使用相對較小的值。不然,Erlang虛擬機可能會失去一些軟實時保證。要使用哪一種大小取決於操做系統/硬件和應用程序的要求。
write(IoDevice, Bytes) -> ok | {error, Reason}
Types:
IoDevice = io_device() | atom()
Bytes = iodata()
Reason = posix() | badarg | terminated
將字節寫入IoDevice引用的文件 。此功能是寫入以原始模式打開的文件的惟一方式(儘管它也適用於一般打開的文件)。若是成功則返回ok ,不然返回{error,Reason}。
若是使用設置爲latin1之外的編碼打開文件,寫入的每一個字節均可能致使實際寫入文件的幾個字節,由於字節範圍0..255可能表示1到4個字節之間的任何值,具體取決於值和UTF編碼類型。
典型的錯誤緣由是:
ebadf
該文件未打開以進行寫入。
enospc
設備上沒有剩餘空間。
write_file(Filename, Bytes) -> ok | {error, Reason}
Types:
Filename = name_all()
Bytes = iodata()
Reason = posix() | badarg | terminated | system_limit
將iodata的內容寫入文件Filename。若是文件不存在,則建立該文件。若是存在,則先前的內容被覆蓋。返回ok,或者{error,Reason}。
典型的錯誤緣由是:
enoent
文件名的一個組件不存在。
enodir
文件名的一個組件不是一個目錄。在某些平臺上,取而代之的是返回enoent。
enospc
設備上沒有剩餘空間。
eacces
缺乏寫入文件或搜索其中一個父目錄的權限。
eisdir
指定的文件是一個目錄。
write_file(Filename, Bytes, Modes) -> ok | {error, Reason}
Types:
Filename = name_all()
Bytes = iodata()
Modes = [mode()]
Reason = posix() | badarg | terminated | system_limit
與write_file/2相同,但採用第三個參數Modes,一個可能模式的列表,請參閱open/2。模式標誌binary和write是隱含的,因此它們不該該被使用。
write_file_info(Filename, FileInfo) -> ok | {error, Reason}
write_file_info(Filename, FileInfo, Opts) -> ok | {error, Reason}
更改文件信息。若是成功則返回ok,不然{error,Reason}。 FileInfo是一個記錄 file_info,在內核包含文件file.hrl中定義 。在調用該函數的模塊中包含如下指令:
-include_lib("kernel/include/file.hrl").
在設定的時間類型atime,mtime和ctime 依賴於設定的時間類型Opts::{time,Type}}。類型local將解釋時間設置爲本地,universal將解釋爲通用時間,posix必須是自1970年1月1日00:00 UTC以前或以前的秒數。默認是{time,local}。
若是給出瞭如下字段,則從記錄中使用。
atime = date_time() | integer()> = 0
上次讀取文件時。
mtime = date_time() | integer()> = 0
上次寫入文件的時間。
ctime = date_time() | integer()> = 0
在Unix上,該字段的任何值將被忽略(文件的「ctime」將被設置爲當前時間)。在Windows上,此字段是爲文件設置的新建立時間。
mode = integer()> = 0
文件權限爲如下位值的總和:
8#00400
讀取權限:全部者
8#00200
寫權限:全部者
8#00100
執行權限:全部者
8#00040
讀權限:組
8#00020
寫入權限:組
8#00010
執行權限:組
8#00004
讀權限:其餘
8#00002
寫入權限:其餘
8#00001
執行權限:其餘
16#800
在執行時設置用戶ID
16#400
執行時設置組ID
在Unix平臺上,能夠設置除上面列出的位以外的其餘位。
uid = integer()> = 0
表示文件的全部者。忽略非Unix文件系統。
gid = integer()> = 0
給出文件全部者屬於的組。忽略非Unix文件系統。
典型的錯誤緣由:
eacces
缺乏文件父目錄之一的搜索權限。
enoent
該文件不存在。
enotdir
文件名的一個組件不是一個目錄。在某些平臺上,取而代之的是返回enoent。
POSIX錯誤代碼
eacces - 權限被拒絕
eagain - 資源暫時不可用
ebadf - 錯誤的文件編號
ebusy - 文件忙
edquot - 超過磁盤配額
eexist - 文件已經存在
efault - 系統調用參數中的錯誤地址
efbig - 文件太大
eintr - 中斷系統調用
einval - 無效的參數
eio - IO錯誤
eisdir - 目錄上的非法操做
eloop - 太多級別的符號連接
emfile - 太多打開的文件
emlink - 太多的連接
enametoolong - 文件名太長
enfile - 文件表溢出
enodev - 沒有這樣的設備
enoent - 沒有這樣的文件或目錄
enomem - 內存不夠
enospc - 設備上沒有剩餘空間
enotblk - 須要塊設備
enotdir - 不是目錄
enotsup - 不支持操做
enxio - 沒有這樣的設備或地址
eperm - 不是全部者
epipe - 破的管道
erofs - 只讀文件系統
espipe - 無效搜尋
esrch - 沒有這樣的進程
estale - 陳舊的遠程文件句柄
exdev - 跨域連接
性能
某些操做系統文件操做(例如,大文件上的sync/1或close/1)可能會阻止其調用線程幾秒鐘。若是這種狀況出如今仿真器主線程中,則響應時間再也不是毫秒數量級,這取決於軟實時系統中「軟」的定義。
若是設備驅動程序線程池處於活動狀態,則文件操做將經過這些線程完成,以便模擬器能夠繼續執行Erlang進程。不幸的是,因爲操做系統須要額外的調度,服務文件操做的時間增長了。
若是設備驅動程序線程池被禁用或大小爲0,則大文件讀取和寫入會被分割爲幾個較小的文件,這使得模擬器能夠在文件操做期間爲其餘進程提供服務。這與使用線程池時的效果相同,但開銷較大。其餘文件操做(例如,大文件上的sync/1或close/1)仍然存在問題。
爲了提升性能,建議使用原始文件。原始文件使用節點主機的文件系統。對於普通文件(非原始文件),文件服務器用於查找文件,若是節點正在將其文件服務器做爲從屬節點運行到其餘節點,而且其餘節點在其餘主機上運行,則它們可能具備不一樣的文件系統。這不多是一個問題,但你如今已經受到警告。
普通文件其實是一個進程,所以它能夠用做IO設備(請參閱io)。所以,當數據寫入普通文件時,將數據發送到文件進程將複製全部非二進制數據。所以建議以二進制模式打開文件並編寫二進制文件。若是文件在另外一個節點上打開,或者文件服務器做爲另外一個節點的從服務器運行,則也會複製二進制文件。
緩存數據以減小文件操做的數量,或者說調用文件驅動程序的次數一般會提升性能。如下函數在測試時在23秒內寫入4 MBytes:
create_file_slow(Name, N) when integer(N), N >= 0 ->
{ok, FD} = file:open(Name, [raw, write, delayed_write, binary]),
ok = create_file_slow(FD, 0, N),
ok = ?FILE_MODULE:close(FD),
ok.
create_file_slow(FD, M, M) ->
ok;
create_file_slow(FD, M, N) ->
ok = file:write(FD, <<M:32/unsigned>>),
create_file_slow(FD, M+1, N).
在每次調用file:write/2以前,如下功能至關的函數將1024個條目收集到128個32字節二進制文件列表中, 並在0.52秒內完成相同的工做,速度提升了44倍。
create_file(Name, N) when integer(N), N >= 0 ->
{ok, FD} = file:open(Name, [raw, write, delayed_write, binary]),
ok = create_file(FD, 0, N),
ok = ?FILE_MODULE:close(FD),
ok.
create_file(FD, M, M) ->
ok;
create_file(FD, M, N) when M + 1024 =< N ->
create_file(FD, M, M + 1024, []),
create_file(FD, M + 1024, N);
create_file(FD, M, N) ->
create_file(FD, M, N, []).
create_file(FD, M, M, R) ->
ok = file:write(FD, R);
create_file(FD, M, N0, R) when M + 8 =< N0 ->
N1 = N0-1, N2 = N0-2, N3 = N0-3, N4 = N0-4,
N5 = N0-5, N6 = N0-6, N7 = N0-7, N8 = N0-8,
create_file(FD, M, N8,
[<<N8:32/unsigned, N7:32/unsigned,
N6:32/unsigned, N5:32/unsigned,
N4:32/unsigned, N3:32/unsigned,
N2:32/unsigned, N1:32/unsigned>> | R]);
create_file(FD, M, N0, R) ->
N1 = N0-1,
create_file(FD, M, N1, [<<N1:32/unsigned>> | R]).
注意
只相信你本身的基準。若是上面的create_file/2中的列表長度增長了,它將運行得稍微快一點,但會消耗更多的內存並致使更多的內存碎片。這對您的應用程序有多大影響是這個簡單的基準測試沒法預測的。
若是每一個二進制文件的大小增長到64字節,它也會運行得稍微快一些,但代碼會笨拙一倍。在當前的實現中,大於64字節的二進制文件存儲在全部進程共有的內存中,而且在進程之間發送時不復制,而這些較小的二進制文件存儲在進程堆中,並在發送時像其餘任何字段同樣進行復制。
所以,對於68字節的二進制大小,create_file/2的運行速度比64字節慢30%,而且會致使更多的內存碎片。請注意,若是要在進程之間發送二進制文件(例如非原始文件),結果可能會徹底不一樣。
原始文件其實是一個端口。將數據寫入端口時,編寫二進制文件列表很是有效。在寫以前,沒有必要將深度列表弄平。在Unix主機上,儘量使用分散輸出(在一個操做中寫入一組緩衝區)。經過這種方式file:write(FD,[Bin1,Bin2 | Bin3])將寫入二進制文件的內容,而不會複製數據,除了可能在操做系統內核深處。
對於原始文件,pwrite/2和pread/2被高效地實現。文件驅動程序只對整個操做調用一次,而且列表迭代在文件驅動程序中完成。
選項delayed_write和read_ahead到 file:open/2使文件驅動程序緩存數據減小操做系統調用的數量。上面示例中的函數 create_file/2須要60秒,而不使用delayed_write選項,速度較慢2.6倍。
並且,做爲一個很是糟糕的例子,create_file_slow/2上面沒有raw,binary和delayed_write選項,也就是它調用file:open(Name,[write]),這個做業須要1分20秒,這比慢3.5倍比第一個例子慢150倍,比優化的create_file/2慢150倍。