Erlang模块file翻译

模块摘要
    文件接口模块
 
描述
    模块file提供了文件系统的接口。
    在具有线程支持的操作系统上,可以让文件操作以其自己的线程执行,从而允许其他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 ...
 
数据类型
deep_list() = [char()| atom()| deep_list() ]
FD()
    表示以原始模式打开的文件的文件描述符。
filename() = string()
filename_all() = string()| binary()
io_device() = pid()| FD()
    由file:open/2文件; pid()是一个处理I/O协议的进程。
name() = string()| atom()| deep_list()
    如果VM处于Unicode文件名模式,则string()和char() 允许大于255。
name_all() = string()| atom()| deep_list()| (RawFilename :: binary())
    如果VM处于Unicode文件名模式,string()和char() 允许大于255. RawFilename是不受Unicode转换影响的文件名,这意味着它可以包含不符合文件系统期望的Unicode编码的字符尽管虚拟机在Unicode文件名模式下启动,但是不支持UTF-8字符)。 
posix() = eacces
        | eagain
        | ebadf
        | ebusy
        | edquot
        | eexist
        | efault
        | efbig
        | eintr
        | einval
        | eio
        | eisdir
        | eloop
        | emfile
        | emlink
        | enametoolong
        | enfile
        | enodev
        | enoent
        | enomem
        | enospc
        | enotblk
        | enotdir
        | enotsup
        | enxio
        | eperm
        | epipe
        | erofs
        | espipe
        | esrch
        | estale
        | exdev
    一个由Unix中使用的POSIX错误代码以及大多数C编译器的运行时库中命名的原子。
date_time() = calendar:datetime()
    必须表示有效的日期和时间。

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 =&lt; 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 =&lt; 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倍。
 
警告
    如果使用io模块访问打开的文件时发生错误,则处理该文件的进程将退出。如果一个进程稍后尝试访问它,死文件进程可能会挂起。这将在未来的版本中修复。
posted @ 2018-07-02 15:21  云彩草原  阅读(1336)  评论(0编辑  收藏  举报