模块摘要
    文件接口模块
 
描述
    模块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模块访问打开的文件时发生错误,则处理该文件的进程将退出。如果一个进程稍后尝试访问它,死文件进程可能会挂起。这将在未来的版本中修复。

Erlang模块file翻译的更多相关文章

  1. Erlang模块erl翻译

    命令:     erl 概述:     Erlang模拟器 描述:     erl程序启动一个Erlang运行时系统.准确的信息是依赖于系统的(举例,erl是否是脚本或程序,其它程序调用).     ...

  2. Erlang模块ets翻译

    概要: 内置的存储 描述: 这个模块是Erlang内置存储BIFs的接口.这些提供了在Erlang运行时系统中存储大量数据的能力,并且能够对数据进行持续的访问时间.(在ordered_set的情况下, ...

  3. Erlang模块inet翻译

    模块 inet 模块概述 访问TCP / IP协议. 描述 此模块提供对TCP/IP协议的访问. 另请参阅<ERTS用户指南:Inet配置>,以获取有关如何配置用于IP通信的Erlang运 ...

  4. Erlang模块gen_server翻译

    gen_server 概要: 通用服务器行为描述: 行为模块实现服务器的客户端-服务器关系.一个通用的服务器进程使用这个模块将实现一组标准的接口功能,包括跟踪和错误报告功能.它也符合OTP进程监控树. ...

  5. Erlang模块gen_fsm翻译

    模块摘要     通用有限状态机行为.   描述     用于实现有限状态机的行为模块.使用该模块实现的通用有限状态机进程(gen_fsm)将具有一组标准的接口函数,并包括用于跟踪和错误报告的功能.它 ...

  6. Erlang模块gen_tcp翻译

    概述 TCP/IP套接字接口 描述 gen_tcp模块提供了使用TCP / IP协议与套接字进行通信的功能. 以下代码片段提供了一个客户端连接到端口5678的服务器的简单示例,传输一个二进制文件并关闭 ...

  7. Erlang模块supervisor翻译

    概要: 通用监督者行为   描述: 一个实现监督者的行为模块,一个监督被称为子进程的其它进程的进程.一个子进程可以是另一个监督者或工作者进程.工作者进程通常的实现使用gen_event,gen_fsm ...

  8. Python模块File文件操作

    Python模块File简介 Python提供了File模块进行文件的操作,他是Python的内置模块.我们在使用File模块的时候,必须先用Popen()函数打开一个文件,在使用结束需要close关 ...

  9. [Erlang25]Erlang in anger 翻译

    Erlang in anger     Erlang in anger 是写Learn some Erlang的帅小伙(照片真是帅死啦)写的,一共87页,可以随意下载(英文原版):http://www ...

随机推荐

  1. 记录一下我做Udacity 的Data Scientist Nano Degree Project

    做项目的时候看了别人的blog,决定自己也随手记录下在做项目中遇到的好的小知识点. 最近在做Udacity的Data Scientist Nano Degree Project的Customer_Se ...

  2. Activity 使用详解

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...

  3. python异常处理-异常捕获-抛出异常-断言-自定义异常-UDP通信-socketserver模块应用-3

    异常捕获 异常:程序在运行过程中出现了不可预知的错误,并且该错误没有对应的处理机制,那么就会以异常的形式表现出来 影响:整个程序无法再正常运行 异常的结构 异常的类型 NameError 异常的信息 ...

  4. Java泛型使用的简单介绍

    目录 一. 泛型是什么 二. 使用泛型有什么好处 三. 泛型类 四. 泛型接口 五. 泛型方法 六. 限定类型变量 七. 泛型通配符 7.1 上界通配符 7.2 下界通配符 7.3 无限定通配符 八. ...

  5. Spring系列(二):Spring IoC应用

    一.Spring IoC的核心概念 IoC(Inversion of Control  控制反转),详细的概念见Spring系列(一):Spring核心概念 二.Spring IoC的应用 1.定义B ...

  6. 【0812 | Day 13】闭包函数/装饰器/迭代器

    目录 闭包函数 无参装饰器 有参装饰器 迭代器 闭包函数 一.什么是闭包? 闭包指的是:函数内部函数对外部作用域而非全局作用域的引用. def outter(): x = 1 def inner(): ...

  7. Oracle Job定时任务详解、跨数据库数据同步

    业务需求,需要与A公司做数据对接,我们公司用的Oracle,A公司用的SQL Server数据库,如何跨数据库建立连接呢?这里使用的是DBLink,不会配置的请看我的另外一篇博客:https://ww ...

  8. Javascript中,实现类与继承的方法和优缺点分析

    Javascript是一种弱类型语言,不存在类的概念,但在js中可以模仿类似于JAVA中的类,实现类与继承 第一种方法:利用Javascript中的原型链 //首先定义一个父类 function An ...

  9. 【hdu 2544最短路】【Dijkstra算法模板题】

    Dijkstra算法 分析 Dijkstra算法适用于边权为正的情况.它可用于计算正权图上的单源最短路( Single-Source Shortest Paths, SSSP) , 即从单个源点出发, ...

  10. 高德全链路压测平台TestPG的架构与实践

    导读 2018年十一当天,高德DAU突破一个亿,不断增长的日活带来喜悦的同时,也给支撑高德业务的技术人带来了挑战.如何保障系统的稳定性,如何保证系统能持续的为用户提供可靠的服务?是所有高德技术人面临的 ...