• 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, )字符分隔,但任何回车符(CR, )后跟换行符也被视为单个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模块访问打开的文件时发生错误,则处理该文件的进程将退出。如果一个进程稍后尝试访问它,死文件进程可能会挂起。这将在未来的版本中修复。
  • 相关阅读:
    sql-DDL, DML 常用语句
    7.8 Structured Streaming
    7.7 输出操作
    7.6 转换操作
    7.5 高级数据源---Kafka
    7.4 基本输入源
    7.3 DStream操作
    7.2 Spark Streaming
    7.1 流计算概述
    6.3 使用Spark SQL读写数据库
  • 原文地址:https://www.cnblogs.com/sunbin-hello/p/9253977.html
Copyright © 2020-2023  润新知