查看源码 file (内核 v10.2)
文件接口模块。
该模块提供了文件系统的接口。
警告
只有通过同一个文件服务器进行文件操作才能保证原子性。在某些操作系统上,例如在 Windows 上重命名现有文件,或者在编写本文时在任何操作系统上执行
write_file_info/2
,NIF 或其他操作系统进程可能会观察到某些操作的中间步骤。
关于文件名编码,Erlang 虚拟机可以在两种模式下运行。可以使用函数 native_name_encoding/0
查询当前模式。它返回 latin1
或 utf8
。
在 latin1
模式下,Erlang 虚拟机不更改文件名的编码。在 utf8
模式下,文件名可以包含大于 255 的 Unicode 字符,并且虚拟机将文件名来回转换为本机文件名编码(通常为 UTF-8,但在 Windows 上为 UTF-16)。
默认模式取决于操作系统。Windows、MacOS X 和 Android 强制执行一致的文件名编码,因此虚拟机使用 utf8
模式。
在具有透明命名(例如,除 MacOS X 之外的所有 Unix 系统)的操作系统上,如果终端支持 UTF-8,则默认值为 utf8
,否则为 latin1
。可以使用 +fnl
(强制使用 latin1
模式)或 +fnu
(强制使用 utf8
模式)在启动 erl
时覆盖默认值。
在具有透明命名的操作系统上,文件名可能会不一致,例如,某些文件以 UTF-8 编码,而另一些文件以 ISO Latin-1 编码。引入了原始文件名的概念,以在 utf8
模式下运行时处理具有不一致命名的文件系统。
原始文件名是指定为二进制文件的文件名。在具有透明命名的系统上,Erlang 虚拟机不会转换指定为二进制文件的文件名。
在 utf8
模式下运行时,函数 list_dir/1
和 read_link/1
永远不会返回原始文件名。要返回所有文件名(包括原始文件名),请使用函数 list_dir_all/1
和 read_link_all/1
。
另请参阅 STDLIB 用户指南中的 关于原始文件名的说明 部分。
注意
文件操作过去接受包含空字符(整数值零)的文件名。这会导致名称被截断,并且在某些情况下,原始操作的参数会被混淆。文件名内部包含空字符的文件名现在被拒绝,并将导致原始文件操作失败。
POSIX 错误代码
eacces
- 权限被拒绝eagain
- 资源暂时不可用ebadf
- 坏的文件号ebusy
- 文件繁忙edquot
- 超出磁盘配额eexist
- 文件已存在efault
- 系统调用参数中的错误地址efbig
- 文件太大eintr
- 系统调用被中断einval
- 无效的参数eio
- I/O 错误eisdir
- 对目录的非法操作eloop
- 符号链接级别过多emfile
- 打开的文件过多emlink
- 链接过多enametoolong
- 文件名太长enfile
- 文件表溢出enodev
- 没有这样的设备enoent
- 没有这样的文件或目录enomem
- 内存不足enospc
- 设备上没有剩余空间enotblk
- 需要块设备enotdir
- 不是目录enotsup
- 不支持的操作enxio
- 没有这样的设备或地址eperm
- 不是所有者epipe
- 管道损坏erofs
- 只读文件系统espipe
- 无效的查找esrch
- 没有这样的进程estale
- 过时的远程文件句柄exdev
- 跨设备链接
性能
为了提高性能,建议使用原始文件。
普通文件实际上是一个进程,因此可以用作 I/O 设备(请参阅 io
)。因此,当数据写入普通文件时,将数据发送到文件进程会复制所有非二进制的数据。因此,建议以二进制模式打开文件并写入二进制文件。如果文件在另一个节点上打开,或者如果文件服务器作为另一个节点的文件服务器的从属服务器运行,则也会复制二进制文件。
注意
原始文件使用节点主机的文件系统。对于普通文件(非原始),文件服务器用于查找文件,如果节点将其文件服务器作为另一个节点的文件服务器的从属服务器运行,并且另一个节点在其他主机上运行,则它们可能具有不同的文件系统。但是,这很少是一个问题。
可以为 open/2
提供选项 delayed_write
和 read_ahead
来启用缓存,这将减少操作系统调用的次数,并大大提高小读取和写入的性能。但是,开销不会完全消失,最好将文件操作的数量保持在最低限度。作为一个人为的示例,以下函数在测试时以 2.5 秒写入 4MB
create_file_slow(Name) ->
{ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
create_file_slow_1(Fd, 4 bsl 20),
file:close(Fd).
create_file_slow_1(_Fd, 0) ->
ok;
create_file_slow_1(Fd, M) ->
ok = file:write(Fd, <<0>>),
create_file_slow_1(Fd, M - 1).
以下功能等效的代码每次调用 write/2
写入 128 字节,因此在 0.08 秒内完成相同的工作,速度快约 30 倍
create_file(Name) ->
{ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
create_file_1(Fd, 4 bsl 20),
file:close(Fd),
ok.
create_file_1(_Fd, 0) ->
ok;
create_file_1(Fd, M) when M >= 128 ->
ok = file:write(Fd, <<0:(128)/unit:8>>),
create_file_1(Fd, M - 128);
create_file_1(Fd, M) ->
ok = file:write(Fd, <<0:(M)/unit:8>>),
create_file_1(Fd, M - 1).
在写入数据时,写入二进制列表通常比写入整数列表更有效。无需在写入之前展平深层列表。在 Unix 主机上,尽可能使用散布输出,该输出在一个操作中写入一组缓冲区。通过这种方式,write(FD, [Bin1, Bin2 | Bin3])
写入二进制文件的内容,而根本不复制数据,除非可能在操作系统内核的深处。
警告
如果在使用模块
io
访问打开的文件时发生错误,则处理该文件的进程将退出。如果进程稍后尝试访问已死的进程,则该进程可能会挂起。这将在未来的版本中修复。
另请参阅
摘要
类型
必须表示有效的日期和时间。
从 file
API 函数返回的文件名。
从 file
API 函数返回的文件名。
由 open/2
返回的 IO 设备。
处理 I/O 协议的进程。
用作 file
API 函数输入的文件名。
一个原子,其名称来自 Unix 中使用的 POSIX 错误代码以及大多数 C 编译器的运行时库。
函数
advise/4
可用于声明未来以特定模式访问文件数据的意图,从而允许操作系统执行适当的优化。
allocate/3
可用于为文件预分配空间。
更改文件的组。请参阅 write_file_info/2
。
更改文件的权限。请参阅 write_file_info/2
。
更改文件的所有者。请参阅 write_file_info/2
。
更改文件的所有者和组。请参阅 write_file_info/2
。
更改文件的修改时间和访问时间。请参阅 write_file_info/2
。
更改文件的修改时间和上次访问时间。请参阅 write_file_info/2
。
关闭 IoDevice
引用的文件。它大多返回 ok
,除了某些严重的错误,例如内存不足。
从 Filename
读取以 .
分隔的 Erlang 术语。返回以下内容之一
从 Source
复制 ByteCount
字节到 Destination
。Source
和 Destination
指的是文件名或 IO 设备,例如,来自 open/2
。
确保操作系统(而不是 Erlang 运行时系统)保留的任何缓冲区都写入磁盘。它在许多方面类似于 fsync
,但它不会更新文件的某些元数据,例如访问时间。在某些平台上,此函数不起作用。
尝试删除目录 Dir
。该目录必须为空才能删除。如果成功,则返回 ok
。
删除文件或目录 File
。如果 File
是一个目录,则首先递归删除其内容。返回
尝试删除文件 Filename
。如果成功,则返回 ok
。
从 Filename
读取和评估以 .
(或 ,
,表达式序列也是一个表达式)分隔的 Erlang 表达式。不会返回评估的结果;文件中的任何表达式序列都必须存在以产生副作用。
给定此模块中任何函数返回的错误原因,返回描述错误的英文字符串。
返回 {ok, Dir}
,其中 Dir
是文件服务器的当前工作目录。
返回 {ok, Dir}
或 {error, Reason}
,其中 Dir
是指定驱动器的当前工作目录。
列出目录中的所有文件,除了原始文件名的文件。如果成功,则返回 {ok, Filenames}
,否则返回 {error, Reason}
。Filenames
是目录中所有文件的名称列表。这些名称未排序。
尝试创建目录 Dir
。不会创建缺失的父目录。如果成功,则返回 ok
。
在支持链接的平台(Unix 和 Windows)上,创建从 Existing
到 New
的硬链接。如果成功创建了链接,则此函数返回 ok
,否则返回 {error, Reason}
。在不支持链接的平台上,返回 {error,enotsup}
。
在支持符号链接的平台(大多数 Unix 系统和从 Vista 开始的 Windows)上,创建指向文件或目录 Existing
的符号链接 New
。Existing
不需要存在。如果成功创建了链接,则返回 ok
,否则返回 {error, Reason}
。在不支持符号链接的平台上,返回 {error, enotsup}
。
以 Modes
确定的模式打开文件 File
,其中 Modes
可以包含以下一个或多个选项
搜索路径 Path
(目录名称列表),直到找到文件 Filename
。如果 Filename
是绝对文件名,则忽略 Path
。然后从文件中读取以 .
分隔的 Erlang 项。
搜索路径 Path
(目录名称列表),直到找到文件 Filename
。如果 Filename
是绝对文件名,则忽略 Path
。然后从文件中读取并计算以 .
(或 ,
,表达式序列也是一个表达式)分隔的 Erlang 表达式。不返回求值结果;文件中任何表达式序列都必须用于其副作用。
搜索路径 Path
(目录名称列表),直到找到文件 Filename
。如果 Filename
是绝对文件名,则忽略 Path
。然后以 Modes
确定的模式打开文件。
搜索路径 Path
(目录名称列表),直到找到文件 Filename
。如果 Filename
是绝对文件名,则忽略 Path
。然后从文件中读取并计算以 .
(或 ,
,表达式序列也是一个表达式)分隔的 Erlang 表达式。
与 path_script/2
相同,但在求值时使用变量绑定 Bindings
。有关变量绑定的信息,请参阅 erl_eval
。
将 IoDevice
引用的文件的位置设置为 Location
。如果成功,则返回 {ok, NewPosition}
(作为绝对偏移量),否则返回 {error, Reason}
。Location
是以下之一
在一个操作中执行一系列 pread/3
,这比一次调用一个效率更高。返回 {ok, [Data, ...]}
或 {error, Reason}
,其中每个 Data
(对应 pread
的结果)要么是列表,要么是二进制数据(取决于文件模式),如果请求的位置超出文件末尾,则为 eof
。
在一个操作中组合 position/2
和 read/2
,这比一次调用一个效率更高。
在一个操作中执行一系列 pwrite/3
,这比一次调用一个效率更高。返回 ok
或 {error, {N, Reason}}
,其中 N
是失败前完成的成功写入次数。
在一个操作中组合 position/2
和 write/2
,这比一次调用一个效率更高。
从 IoDevice
引用的文件中读取 Number
个字节/字符。
返回 {ok, Binary}
,其中 Binary
是一个二进制数据对象,包含 Filename
的内容,如果发生错误,则返回 {error, Reason}
。
检索有关文件的信息。如果成功,则返回 {ok, FileInfo}
,否则返回 {error, Reason}
。
从 IoDevice
引用的文件中读取一行字节/字符。
如果 Name
指的是符号链接,则返回 {ok, Filename}
,否则返回 {error, Reason}
。在不支持符号链接的平台上,返回值是 {error,enotsup}
。
与 read_file_info/1,2
的工作方式相同,但如果 Name
是符号链接,则有关该链接的信息将返回到 file_info
记录中,并且记录的 type
字段设置为 symlink
。
尝试将文件 Source
重命名为 Destination
。它可以用于在目录之间移动文件(和目录),但仅指定目标是不够的。还必须指定目标文件名。例如,如果 bar
是一个普通文件,foo
和 baz
是目录,则 rename("foo/bar", "baz")
返回错误,但 rename("foo/bar", "baz/bar")
成功。如果成功,则返回 ok
。
从文件中读取并计算以 .
(或 ,
,表达式序列也是一个表达式)分隔的 Erlang 表达式。
将文件 Filename
发送到 Socket
。如果成功,则返回 {ok, BytesSent}
,否则返回 {error, Reason}
。
将从 RawFile
引用的文件中,从 Offset
开始的 Bytes
发送到 Socket
。如果成功,则返回 {ok, BytesSent}
,否则返回 {error, Reason}
。如果 Bytes
设置为 0
,则会发送指定 Offset
之后的所有数据。
将文件服务器的当前工作目录设置为 Dir
。如果成功,则返回 ok
。
确保操作系统(而不是 Erlang 运行时系统)保留的任何缓冲区都写入磁盘。在某些平台上,此函数可能不起作用。
在当前位置截断 IoDevice
引用的文件。如果成功,则返回 ok
,否则返回 {error, Reason}
。
将 Bytes
写入 IoDevice
引用的文件。此函数是写入以 raw
模式打开的文件的唯一方法(尽管它也适用于正常打开的文件)。如果成功,则返回 ok
,否则返回 {error, Reason}
。
将 iodata
项 Bytes
的内容写入文件 Filename
。如果文件不存在,则创建该文件。如果文件存在,则会覆盖先前的内容。如果成功,则返回 ok
,否则返回 {error, Reason}
。
与 write_file/2
相同,但采用第三个参数 Modes
(可能的模式列表),请参阅 open/2
。模式标志 binary
和 write
是隐式的,因此不应使用它们。
更改文件信息。如果成功,则返回 ok
,否则返回 {error, Reason}
。
类型
-type date_time() :: calendar:datetime().
必须表示有效的日期和时间。
-type delete_option() :: raw.
-type fd() :: file_descriptor().
一个文件描述符,表示以 raw
模式打开的文件。
-type file_info() :: #file_info{size :: non_neg_integer() | undefined, type :: device | directory | other | regular | symlink | undefined, access :: read | write | read_write | none | undefined, atime :: file:date_time() | non_neg_integer() | undefined, mtime :: file:date_time() | non_neg_integer() | undefined, ctime :: file:date_time() | non_neg_integer() | undefined, mode :: non_neg_integer() | undefined, links :: non_neg_integer() | undefined, major_device :: non_neg_integer() | undefined, minor_device :: non_neg_integer() | undefined, inode :: non_neg_integer() | undefined, uid :: non_neg_integer() | undefined, gid :: non_neg_integer() | undefined}.
-type file_info_option() :: {time, local} | {time, universal} | {time, posix} | raw.
-type filename() :: string().
从 file
API 函数返回的文件名。
请参阅 name_all/0
类型的文档。
从 file
API 函数返回的文件名。
请参阅 name_all/0
类型的文档。
由 open/2
返回的 IO 设备。
默认返回 io_server/0
,如果给定 raw
选项,则返回 fd/0
。
-type io_server() :: pid().
处理 I/O 协议的进程。
-type mode() :: read | write | append | exclusive | raw | binary | {delayed_write, Size :: non_neg_integer(), Delay :: non_neg_integer()} | delayed_write | {read_ahead, Size :: pos_integer()} | read_ahead | compressed | compressed_one | {encoding, unicode:encoding()} | sync.
用作 file
API 函数输入的受限文件名。
如果虚拟机处于 Unicode 文件名模式,则允许 string/0
和 char/0
大于 255。另请参阅 name_all/0
类型的文档。
用作 file
API 函数输入的文件名。
如果虚拟机处于 Unicode 文件名模式,则允许字符大于 255。RawFilename
是不受 Unicode 转换的文件名,这意味着它可以包含不符合文件系统预期 Unicode 编码的字符(即,即使虚拟机以 Unicode 文件名模式启动,也可能包含非 UTF-8 字符)。空字符(整数值零)在文件名中是不允许的(即使在末尾也不允许)。
-type posix() ::
eacces | eagain | ebadf | ebadmsg | ebusy | edeadlk | edeadlock | edquot | eexist | efault |
efbig | eftype | eintr | einval | eio | eisdir | eloop | emfile | emlink | emultihop |
enametoolong | enfile | enobufs | enodev | enolck | enolink | enoent | enomem | enospc |
enosr | enostr | enosys | enotblk | enotdir | enotsup | enxio | eopnotsupp | eoverflow |
eperm | epipe | erange | erofs | espipe | esrch | estale | etxtbsy | exdev.
一个原子,其名称来自 Unix 中使用的 POSIX 错误代码以及大多数 C 编译器的运行时库。
-type posix_file_advise() :: normal | sequential | random | no_reuse | will_need | dont_need.
-type read_file_option() :: raw.
-type sendfile_option() :: {chunk_size, non_neg_integer()} | {use_threads, boolean()}.
函数
-spec advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason} when IoDevice :: io_device(), Offset :: integer(), Length :: integer(), Advise :: posix_file_advise(), Reason :: posix() | badarg.
advise/4
可用于声明未来以特定模式访问文件数据的意图,从而允许操作系统执行适当的优化。
在某些平台上,此函数可能不起作用。
-spec allocate(File, Offset, Length) -> ok | {error, posix()} when File :: io_device(), Offset :: non_neg_integer(), Length :: non_neg_integer().
allocate/3
可用于为文件预分配空间。
此函数仅在提供此功能的平台上成功。
-spec change_group(Filename, Gid) -> ok | {error, Reason} when Filename :: name_all(), Gid :: integer(), Reason :: posix() | badarg.
更改文件的组。请参阅 write_file_info/2
。
-spec change_mode(Filename, Mode) -> ok | {error, Reason} when Filename :: name_all(), Mode :: integer(), Reason :: posix() | badarg.
更改文件的权限。请参阅 write_file_info/2
。
-spec change_owner(Filename, Uid) -> ok | {error, Reason} when Filename :: name_all(), Uid :: integer(), Reason :: posix() | badarg.
更改文件的所有者。请参阅 write_file_info/2
。
-spec change_owner(Filename, Uid, Gid) -> ok | {error, Reason} when Filename :: name_all(), Uid :: integer(), Gid :: integer(), Reason :: posix() | badarg.
更改文件的所有者和组。请参阅 write_file_info/2
。
-spec change_time(Filename, Mtime) -> ok | {error, Reason} when Filename :: name_all(), Mtime :: date_time(), Reason :: posix() | badarg.
更改文件的修改时间和访问时间。请参阅 write_file_info/2
。
-spec change_time(Filename, Atime, Mtime) -> ok | {error, Reason} when Filename :: name_all(), Atime :: date_time(), Mtime :: date_time(), Reason :: posix() | badarg.
更改文件的修改时间和上次访问时间。请参阅 write_file_info/2
。
-spec close(IoDevice) -> ok | {error, Reason} when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.
关闭 IoDevice
引用的文件。它大多返回 ok
,除了某些严重的错误,例如内存不足。
请注意,如果在打开文件时使用了 delayed_write
选项,则 close/1
可能会返回旧的写入错误,甚至不会尝试关闭文件。请参阅 open/2
。
-spec consult(Filename) -> {ok, Terms} | {error, Reason} when Filename :: name_all(), Terms :: [term()], Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
从 Filename
读取以 .
分隔的 Erlang 术语。返回以下内容之一
{ok, Terms}
- 文件已成功读取。{error, atom()}
- 打开文件或读取文件时发生错误。有关典型错误代码的列表,请参阅open/2
。{error, {Line, Mod, Term}}
- 在解释文件中的 Erlang 项时发生错误。要将三元素元组转换为错误英文描述,请使用format_error/1
。
示例
f.txt: {person, "kalle", 25}.
{person, "pelle", 30}.
1> file:consult("f.txt").
{ok,[{person,"kalle",25},{person,"pelle",30}]}
可以使用注释设置 Filename
的编码,如 epp
中所述。
-spec copy(Source, Destination) -> {ok, BytesCopied} | {error, Reason} when Source :: io_device() | Filename | {Filename, Modes}, Destination :: io_device() | Filename | {Filename, Modes}, Filename :: name_all(), Modes :: [mode()], BytesCopied :: non_neg_integer(), Reason :: posix() | badarg | terminated.
-spec copy(Source, Destination, ByteCount) -> {ok, BytesCopied} | {error, Reason} when Source :: io_device() | Filename | {Filename, Modes}, Destination :: io_device() | Filename | {Filename, Modes}, Filename :: name_all(), Modes :: [mode()], ByteCount :: non_neg_integer() | infinity, BytesCopied :: non_neg_integer(), Reason :: posix() | badarg | terminated.
从 Source
复制 ByteCount
字节到 Destination
。Source
和 Destination
指的是文件名或 IO 设备,例如,来自 open/2
。
参数 Modes
是可能的模式列表,请参阅 open/2
,默认为 []
。
如果 Source
和 Destination
都引用文件名,则分别在其模式列表的前面加上 [read, binary]
和 [write, binary]
打开文件,以优化复制。
如果 Source
引用文件名,则在复制之前,会将其模式列表的前面加上 read
模式打开,并在完成后关闭。
如果 Destination
引用文件名,则在复制之前,会将其模式列表的前面加上 write
模式打开,并在完成后关闭。
返回 {ok, BytesCopied}
,其中 BytesCopied
是复制的字节数,如果源上遇到文件结尾,则该值可能小于 ByteCount
。如果操作失败,则返回 {error, Reason}
。
-spec datasync(IoDevice) -> ok | {error, Reason} when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.
确保操作系统(而不是 Erlang 运行时系统)保留的任何缓冲区都写入磁盘。它在许多方面类似于 fsync
,但它不会更新文件的某些元数据,例如访问时间。在某些平台上,此函数不起作用。
访问数据库或日志文件的应用程序通常会写入一个很小的数据片段(例如,日志文件中的一行),然后立即调用 fsync()
以确保写入的数据已物理存储在硬盘上。不幸的是,fsync()
始终会启动两个写操作:一个用于新写入的数据,另一个用于更新存储在 inode
中的修改时间。如果修改时间不是事务概念的一部分,则可以使用 fdatasync()
来避免不必要的 inode
磁盘写操作。
仅在某些 POSIX 系统中可用,此调用会导致调用 fsync()
,或者在不提供 fdatasync()
系统调用的系统中无效。
尝试删除目录 Dir
。该目录必须为空才能删除。如果成功,则返回 ok
。
典型的错误原因
eacces
- 缺少Dir
的父目录的搜索或写入权限。eexist
- 该目录不为空。enoent
- 该目录不存在。enotdir
-Dir
的组件不是目录。在某些平台上,返回enoent
。einval
- 尝试删除当前目录。在某些平台上,返回eacces
。
删除文件或目录 File
。如果 File
是一个目录,则首先递归删除其内容。返回
ok
- 操作完成,没有错误。{error, posix()}
- 访问或删除File
时发生错误。如果无法删除File
下的某些文件或目录,则无法删除File
,因为它不是空的,并返回{error, eexist}
。
-spec delete(Filename) -> ok | {error, Reason} when Filename :: name_all(), Reason :: posix() | badarg.
等效于 delete(Filename, [])
。
-spec delete(Filename, Opts) -> ok | {error, Reason} when Filename :: name_all(), Opts :: [delete_option()], Reason :: posix() | badarg.
尝试删除文件 Filename
。如果成功,则返回 ok
。
如果设置了 raw
选项,则不会调用文件服务器。这在文件服务器尚未注册的早期引导阶段尤其有用,以便仍然能够删除本地文件。
典型的错误原因
enoent
- 该文件不存在。eacces
- 缺少文件或其父级之一的权限。eperm
- 该文件是一个目录,并且用户不是超级用户。enotdir
- 文件名的组件不是目录。在某些平台上,返回enoent
。einval
-Filename
的类型不正确,例如元组。
警告
在未来的版本中,参数
Filename
的错误类型可能会生成异常。
-spec eval(Filename) -> ok | {error, Reason} when Filename :: name_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
从 Filename
读取和评估以 .
(或 ,
,表达式序列也是一个表达式)分隔的 Erlang 表达式。不会返回评估的结果;文件中的任何表达式序列都必须存在以产生副作用。
返回以下其中一项
ok
- 已读取并评估该文件。{error, atom()}
- 打开文件或读取文件时发生错误。有关典型错误代码的列表,请参阅open/2
。{error, {Line, Mod, Term}}
- 在解释文件中的 Erlang 表达式时发生错误。要将三元素元组转换为错误的英文描述,请使用format_error/1
。
可以使用注释设置 Filename
的编码,如 epp
中所述。
-spec format_error(Reason) -> Chars when Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}, Chars :: string().
给定此模块中任何函数返回的错误原因,返回描述错误的英文字符串。
返回 {ok, Dir}
,其中 Dir
是文件服务器的当前工作目录。
注意
在极少数情况下,此函数在 Unix 上可能会失败。如果当前目录的父目录不存在读取权限,则可能会发生这种情况。
典型的错误原因
eacces
- 缺少当前目录的父目录之一的读取权限。
-spec get_cwd(Drive) -> {ok, Dir} | {error, Reason} when Drive :: string(), Dir :: filename(), Reason :: posix() | badarg.
返回 {ok, Dir}
或 {error, Reason}
,其中 Dir
是指定驱动器的当前工作目录。
Drive
的形式应为 Letter:
,例如 c:
。
在没有当前驱动器概念的平台(例如,Unix)上返回 {error, enotsup}
。
典型的错误原因
enotsup
- 操作系统没有驱动器的概念。eacces
- 该驱动器不存在。einval
-Drive
的格式无效。
-spec list_dir(Dir) -> {ok, Filenames} | {error, Reason} when Dir :: name_all(), Filenames :: [filename()], Reason :: posix() | badarg | {no_translation, Filename :: unicode:latin1_binary()}.
列出目录中的所有文件,除了原始文件名的文件。如果成功,则返回 {ok, Filenames}
,否则返回 {error, Reason}
。Filenames
是目录中所有文件的名称列表。这些名称未排序。
典型的错误原因
eacces
- 缺少Dir
或其父目录之一的搜索或写入权限。enoent
- 该目录不存在。{no_translation, Filename}
-Filename
是一个以 ISO Latin-1 编码的字符的binary/0
,并且虚拟机以参数+fnue
启动。
-spec list_dir_all(Dir) -> {ok, Filenames} | {error, Reason} when Dir :: name_all(), Filenames :: [filename_all()], Reason :: posix() | badarg.
列出目录中的所有文件,包括带有原始文件名的文件。如果成功,则返回 {ok, Filenames}
,否则返回 {error, Reason}
。Filenames
是目录中所有文件的名称列表。这些名称未排序。
典型的错误原因
eacces
- 缺少Dir
或其父目录之一的搜索或写入权限。enoent
- 该目录不存在。
尝试创建目录 Dir
。不会创建缺失的父目录。如果成功,则返回 ok
。
典型的错误原因
eacces
- 缺少Dir
的父目录的搜索或写入权限。eexist
- 名为Dir
的文件或目录已存在。enoent
-Dir
的组件不存在。enospc
- 设备上没有剩余空间。enotdir
-Dir
的组件不是目录。在某些平台上,返回enoent
。
-spec make_link(Existing, New) -> ok | {error, Reason} when Existing :: name_all(), New :: name_all(), Reason :: posix() | badarg.
在支持链接的平台(Unix 和 Windows)上,创建从 Existing
到 New
的硬链接。如果成功创建了链接,则此函数返回 ok
,否则返回 {error, Reason}
。在不支持链接的平台上,返回 {error,enotsup}
。
典型的错误原因
eacces
- 缺少对Existing
或New
的父目录的读取或写入权限。eexist
-New
已经存在。enotsup
- 此平台不支持硬链接。
-spec make_symlink(Existing, New) -> ok | {error, Reason} when Existing :: name_all(), New :: name_all(), Reason :: posix() | badarg.
在支持符号链接的平台(大多数 Unix 系统和从 Vista 开始的 Windows)上,创建指向文件或目录 Existing
的符号链接 New
。Existing
不需要存在。如果成功创建了链接,则返回 ok
,否则返回 {error, Reason}
。在不支持符号链接的平台上,返回 {error, enotsup}
。
典型的错误原因
eacces
- 缺少对Existing
或New
的父目录的读取或写入权限。eexist
-New
已经存在。enotsup
- 此平台不支持符号链接。eperm
- 用户没有创建符号链接的权限(Windows 上为SeCreateSymbolicLinkPrivilege
)。
-spec native_name_encoding() -> latin1 | utf8.
返回文件名编码模式。如果为 latin1
,则系统不转换文件名。如果为 utf8
,则文件名会与本地文件名编码(通常为 UTF-8,但在 Windows 上为 UTF-16)之间来回转换。
-spec open(File, Modes) -> {ok, IoDevice} | {error, Reason} when File :: Filename | iodata(), Filename :: name_all(), Modes :: [mode() | ram | directory], IoDevice :: io_device(), Reason :: posix() | badarg | system_limit.
以 Modes
确定的模式打开文件 File
,其中 Modes
可以包含以下一个或多个选项
read
- 打开文件以进行读取,文件必须存在。write
- 打开文件以进行写入。如果文件不存在,则会创建该文件。如果文件存在并且write
未与read
组合使用,则会截断该文件。append
- 打开文件以进行写入。如果文件不存在,则会创建该文件。每次对以append
方式打开的文件执行写入操作时,都会在文件末尾进行。exclusive
- 打开文件以进行写入。如果文件不存在,则会创建该文件。如果文件存在,则返回{error, eexist}
。警告
此选项不保证在不支持
O_EXCL
的文件系统(如 NFS)上的独占性。除非您知道文件系统支持它(一般来说,本地文件系统是安全的),否则请不要依赖此选项。raw
- 允许更快地访问文件,因为不需要 Erlang 进程来处理文件。但是,以这种方式打开的文件有以下限制:io
模块中的函数不能使用,因为它们只能与 Erlang 进程通信。而是使用函数read/2
、read_line/1
和write/2
。- 特别是如果要在
raw
文件上使用read_line/1
,建议将此选项与选项{read_ahead, Size}
结合使用,因为没有缓冲的面向行的 I/O 效率较低。 - 只有打开该文件的 Erlang 进程才能使用它。
- 不能使用远程 Erlang 文件服务器。运行 Erlang 节点的计算机必须可以访问文件系统(直接或通过 NFS)。
binary
- 对文件执行读取操作时返回二进制数据而不是列表。{delayed_write, Size, Delay}
- 后续write/2
调用中的数据会被缓冲,直到缓冲至少Size
个字节,或者直到最早的缓冲数据达到Delay
毫秒。然后,所有缓冲数据在一个操作系统调用中写入。在执行其他文件操作(而非write/2
)之前,缓冲数据也会被刷新。此选项的目的是通过减少操作系统调用的次数来提高性能。因此,
write/2
调用的数据大小必须明显小于Size
,并且不能穿插太多其他文件操作。使用此选项时,
write/2
调用的结果可能会提前报告为成功,如果发生写入错误,则该错误将报告为下一个文件操作的结果,而该操作不会执行。例如,当使用
delayed_write
时,在多次调用write/2
后,close/1
可能会返回{error, enospc}
,因为磁盘上没有足够的空间来存储先前写入的数据。close/1
可能必须再次调用,因为文件仍然处于打开状态。delayed_write
- 与{delayed_write, Size, Delay}
相同,但Size
和Delay
使用合理的默认值(大约 64 KB,2 秒)。{read_ahead, Size}
- 激活读取数据缓冲。如果read/2
调用的字节数明显小于Size
,则仍会针对Size
字节的块执行对操作系统的读取操作。额外的未读数据会被缓冲,并在后续read/2
调用中返回,从而减少操作系统调用的次数,提高性能。read_ahead
缓冲区也被函数read_line/1
在raw
模式下大量使用,因此,当使用该函数访问原始文件时,建议使用此选项(出于性能考虑)。如果
read/2
调用的字节数不明显小于,甚至大于Size
字节,则无法获得性能提升。read_ahead
- 与{read_ahead, Size}
相同,但Size
使用合理的默认值(大约 64 KB)。compressed
- 使读取或写入 gzip 压缩文件成为可能。选项compressed
必须与read
或write
组合使用,但不能同时使用。请注意,使用read_file_info/1
获取的文件大小可能与可以从压缩文件中读取的字节数不匹配。compressed_one
- 读取 gzip 压缩文件的一个成员。选项compressed_one
只能与read
组合使用。{encoding, Encoding}
- 使文件能够自动将字符转换为特定(Unicode)编码,并从中转换。请注意,提供给write/2
或由read/2
返回的数据仍然是面向字节的;此选项仅表示数据如何存储在磁盘文件中。根据编码的不同,首选不同的读取和写入数据的方法。
latin1
的默认编码意味着使用此模块(file
)进行数据的读取和写入,因为此处提供的接口使用面向字节的数据。使用其他(Unicode)编码使io
函数get_chars
、get_line
和put_chars
更合适,因为它们可以使用完整的 Unicode 范围。如果将无法转换为指定编码的格式的数据发送到
io_device/0
,或者如果由返回的数据的格式无法处理数据字符范围的函数读取数据,则会发生错误并关闭该文件。Encoding
的允许值:latin1
- 默认编码。提供给文件的字节(即write/2
)会“按原样”写入文件。同样,从文件读取的字节(即read/2
)也会“按原样”返回。如果使用模块io
进行写入,则该文件只能处理代码点不超过 255 的 Unicode 字符(ISO Latin-1 范围)。unicode
或utf8
- 字符在写入文件或从文件读取之前会转换为 UTF-8 编码。以这种方式打开的文件可以使用函数read/2
读取,只要存储在文件上的数据不超过 ISO Latin-1 范围 (0..255),但是如果数据包含超出该范围的 Unicode 代码点,则会发生故障。最好使用 Unicode 感知模块io
中的函数读取文件。通过任何方式写入文件的字节都会转换为 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 之外,然后在进一步读取之前设置为正确的编码。有关识别 BOM 的函数,请参阅模块unicode
。此选项不允许用于
raw
文件。ram
-File
必须为iodata/0
。返回一个fd/0
,它使模块file
能够像操作文件一样操作内存中的数据。sync
- 在支持它的平台上,启用 POSIXO_SYNC
同步 I/O 标志或其平台相关的等效项(例如,Windows 上的FILE_FLAG_WRITE_THROUGH
),以便在数据物理写入磁盘之前,对文件的写入操作会被阻止。但是,请注意,此标志的确切语义因平台而异。例如,Linux 或 Windows 都不能保证在调用返回之前也会写入所有文件元数据。对于精确的语义,请检查平台文档的详细信息。在不支持 POSIXO_SYNC
或等效项的平台上,使用sync
标志会导致open
返回{error, enotsup}
。directory
- 允许open
在目录上工作。
返回:
{ok, IoDevice}
- 文件以请求的模式打开。IoDevice
是对文件的引用。{error, Reason}
- 无法打开文件。
IoDevice
实际上是处理该文件的进程的 pid。此进程会监视最初打开该文件的进程(所有者进程)。如果所有者进程终止,则该文件将关闭,并且该进程本身也会终止。从此调用返回的 IoDevice
可用作 I/O 函数的参数(请参阅 io
)。
警告
虽然此函数可用于打开任何文件,但我们不建议将其用于 NFS 挂载的文件、FIFO、设备或类似文件,因为它们可能会导致 IO 线程永远挂起。
如果您的应用程序需要与这些类型的文件进行交互,我们建议将这些部分分解为端口程序。
注意
在之前的
file
版本中,模式被指定为原子read
、write
或read_write
中的一个,而不是列表。为了向后兼容,仍然允许这种方式,但不应在新代码中使用。另请注意,read_write
不允许在模式列表中使用。
典型的错误原因
enoent
- 该文件不存在。eacces
- 缺少读取文件或搜索父目录之一的权限。eisdir
- 指定的文件是一个目录。enotdir
- 文件名的组成部分不是目录,或者如果指定了directory
模式,则文件名本身不是目录。在某些平台上,会返回enoent
。enospc
- 设备上没有剩余空间(如果指定了write
访问权限)。
-spec path_consult(Path, Filename) -> {ok, Terms, FullName} | {error, Reason} when Path :: [Dir], Dir :: name_all(), Filename :: name_all(), Terms :: [term()], FullName :: filename_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
搜索路径 Path
(目录名称列表),直到找到文件 Filename
。如果 Filename
是绝对文件名,则忽略 Path
。然后从文件中读取以 .
分隔的 Erlang 项。
返回以下其中一项
{ok, Terms, FullName}
- 文件读取成功。FullName
是文件的完整名称。{error, enoent}
- 在Path
中的任何目录中都找不到该文件。{error, atom()}
- 打开文件或读取文件时发生错误。有关典型错误代码的列表,请参阅open/2
。{error, {Line, Mod, Term}}
- 解释文件中的 Erlang 项时发生错误。使用format_error/1
将三元素元组转换为错误的英文描述。
Filename
的编码可以通过注释进行设置,如 epp
中所述。
-spec path_eval(Path, Filename) -> {ok, FullName} | {error, Reason} when Path :: [Dir :: name_all()], Filename :: name_all(), FullName :: filename_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
搜索路径 Path
(目录名称列表),直到找到文件 Filename
。如果 Filename
是绝对文件名,则忽略 Path
。然后从文件中读取并计算以 .
(或 ,
,表达式序列也是一个表达式)分隔的 Erlang 表达式。不返回求值结果;文件中任何表达式序列都必须用于其副作用。
返回以下其中一项
{ok, FullName}
- 文件已读取并求值。FullName
是文件的完整名称。{error, enoent}
- 在Path
中的任何目录中都找不到该文件。{error, atom()}
- 打开文件或读取文件时发生错误。有关典型错误代码的列表,请参阅open/2
。{error, {Line, Mod, Term}}
- 解释文件中的 Erlang 表达式时发生错误。使用format_error/1
将三元素元组转换为错误的英文描述。
Filename
的编码可以通过注释进行设置,如 epp
中所述。
-spec path_open(Path, Filename, Modes) -> {ok, IoDevice, FullName} | {error, Reason} when Path :: [Dir :: name_all()], Filename :: name_all(), Modes :: [mode() | directory], IoDevice :: io_device(), FullName :: filename_all(), Reason :: posix() | badarg | system_limit.
搜索路径 Path
(目录名称列表),直到找到文件 Filename
。如果 Filename
是绝对文件名,则忽略 Path
。然后以 Modes
确定的模式打开文件。
返回以下其中一项
{ok, IoDevice, FullName}
- 文件以请求的模式打开。IoDevice
是对文件的引用,FullName
是文件的完整名称。{error, enoent}
- 在Path
中的任何目录中都找不到该文件。{error, atom()}
- 无法打开文件。
-spec path_script(Path, Filename) -> {ok, Value, FullName} | {error, Reason} when Path :: [Dir :: name_all()], Filename :: name_all(), Value :: term(), FullName :: filename_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
搜索路径 Path
(目录名称列表),直到找到文件 Filename
。如果 Filename
是绝对文件名,则忽略 Path
。然后从文件中读取并计算以 .
(或 ,
,表达式序列也是一个表达式)分隔的 Erlang 表达式。
返回以下其中一项
{ok, Value, FullName}
- 文件已读取并求值。FullName
是文件的完整名称,Value
是最后一个表达式的值。{error, enoent}
- 在Path
中的任何目录中都找不到该文件。{error, atom()}
- 打开文件或读取文件时发生错误。有关典型错误代码的列表,请参阅open/2
。{error, {Line, Mod, Term}}
- 解释文件中的 Erlang 表达式时发生错误。使用format_error/1
将三元素元组转换为错误的英文描述。
Filename
的编码可以通过注释进行设置,如 epp
中所述。
-spec path_script(Path, Filename, Bindings) -> {ok, Value, FullName} | {error, Reason} when Path :: [Dir :: name_all()], Filename :: name_all(), Bindings :: erl_eval:binding_struct(), Value :: term(), FullName :: filename_all(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
与 path_script/2
相同,但在求值时使用变量绑定 Bindings
。有关变量绑定的信息,请参阅 erl_eval
。
-spec position(IoDevice, Location) -> {ok, NewPosition} | {error, Reason} when IoDevice :: io_device(), Location :: location(), NewPosition :: integer(), Reason :: posix() | badarg | terminated.
将 IoDevice
引用的文件的位置设置为 Location
。如果成功,则返回 {ok, NewPosition}
(作为绝对偏移量),否则返回 {error, Reason}
。Location
是以下之一
Offset
- 与{bof, Offset}
相同。{bof, Offset}
- 绝对偏移量。{cur, Offset}
- 从当前位置的偏移量。{eof, Offset}
- 从文件末尾的偏移量。bof | cur | eof
- 与上面相同,但Offset
为 0。
请注意,偏移量以字节为单位计数,而不是以字符为单位。如果使用 latin1
以外的其他 encoding
打开文件,则一个字节不对应一个字符。在此类文件中进行定位只能在已知的字符边界上进行。也就是说,可以定位到先前通过获取当前位置检索到的位置、文件的开头/结尾,或者通过其他方式(通常超出文件中具有已知字节大小的字节顺序标记)已知在正确的字符边界上的其他位置。
一个典型的错误原因是
einval
-Location
非法,或者它被计算为文件中负偏移量。请注意,如果结果位置为负值,则结果为错误,并且在调用后,文件位置未定义。
-spec pread(IoDevice, LocNums) -> {ok, DataL} | eof | {error, Reason} when IoDevice :: io_device(), LocNums :: [{Location :: location(), Number :: non_neg_integer()}], DataL :: [Data], Data :: string() | binary() | eof, Reason :: posix() | badarg | terminated.
在一个操作中执行一系列 pread/3
,这比一次调用一个效率更高。返回 {ok, [Data, ...]}
或 {error, Reason}
,其中每个 Data
(对应 pread
的结果)要么是列表,要么是二进制数据(取决于文件模式),如果请求的位置超出文件末尾,则为 eof
。
由于位置被指定为字节偏移量,因此在处理 encoding
设置为 latin1
以外的值的文件时,请格外小心,因为并非每个字节位置都是此类文件上的有效字符边界。
-spec pread(IoDevice, Location, Number) -> {ok, Data} | eof | {error, Reason} when IoDevice :: io_device(), Location :: location(), Number :: non_neg_integer(), Data :: string() | binary(), Reason :: posix() | badarg | terminated.
在一个操作中组合 position/2
和 read/2
,这比一次调用一个效率更高。
仅当 Location
为 raw
和 ram
模式时,才允许为整数。
对于 raw
模式,操作后文件的当前位置未定义;对于 ram
模式,则保持不变。
由于位置被指定为字节偏移量,因此在处理 encoding
设置为 latin1
以外的值的文件时,请格外小心,因为并非每个字节位置都是此类文件上的有效字符边界。
-spec pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}} when IoDevice :: io_device(), LocBytes :: [{Location :: location(), Bytes :: iodata()}], N :: non_neg_integer(), Reason :: posix() | badarg | terminated.
在一个操作中执行一系列 pwrite/3
,这比一次调用一个效率更高。返回 ok
或 {error, {N, Reason}}
,其中 N
是失败前完成的成功写入次数。
当在 encoding
设置为 latin1
以外的值的文件中进行定位时,必须注意将位置设置在正确的字符边界上。有关详细信息,请参阅 position/2
。
-spec pwrite(IoDevice, Location, Bytes) -> ok | {error, Reason} when IoDevice :: io_device(), Location :: location(), Bytes :: iodata(), Reason :: posix() | badarg | terminated.
在一个操作中组合 position/2
和 write/2
,这比一次调用一个效率更高。
仅当 Location
为 raw
和 ram
模式时,才允许为整数。
对于 raw
模式,操作后文件的当前位置未定义;对于 ram
模式,则保持不变。
当在 encoding
设置为 latin1
以外的值的文件中进行定位时,必须注意将位置设置在正确的字符边界上。有关详细信息,请参阅 position/2
。
-spec read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason} when IoDevice :: io_device() | io:device(), Number :: non_neg_integer(), Data :: string() | binary(), Reason :: posix() | badarg | terminated | {no_translation, unicode, latin1}.
从 IoDevice
引用的文件中读取 Number
个字节/字符。
函数 read/2
、pread/3
和 read_line/1
是从以 raw
模式打开的文件中读取的唯一方法(尽管它们也适用于正常打开的文件)。
对于 encoding
设置为 latin1
以外的值的文件,一个字符可以用文件中的多个字节表示。参数 Number
始终表示从文件中读取的字符数,而读取 Unicode 文件时,文件中位置的移动可能远远超过此数字。
此外,如果 encoding
设置为 latin1
以外的值,则如果数据包含大于 255 的字符,则 read/2
调用将失败,这就是为什么在读取此类文件时首选 io:get_chars/3
的原因。
该函数返回
{ok, Data}
- 如果文件以二进制模式打开,则读取的字节在二进制文件中返回,否则在列表中返回。如果到达文件末尾,则列表或二进制文件比请求的字节数短。eof
- 如果Number>0
并且在读取任何内容之前就到达了文件末尾,则返回。{error, Reason}
- 发生错误。
典型的错误原因
ebadf
- 文件未打开以进行读取。{no_translation, unicode, latin1}
- 该文件使用latin1
以外的其他encoding
打开,并且文件中的数据无法转换为此函数返回的面向字节的数据。
-spec read_file(Filename, Opts) -> {ok, Binary} | {error, Reason} when Filename :: name_all(), Opts :: [read_file_option()], Binary :: binary(), Reason :: posix() | badarg | terminated | system_limit.
返回 {ok, Binary}
,其中 Binary
是一个二进制数据对象,包含 Filename
的内容,如果发生错误,则返回 {error, Reason}
。
如果设置了选项 raw
,则不会调用文件服务器。
典型的错误原因
enoent
- 该文件不存在。eacces
- 缺少读取文件或搜索父目录之一的权限。eisdir
- 指定的文件是一个目录。enotdir
- 文件名的组件不是目录。在某些平台上,返回enoent
。enomem
- 没有足够的内存来存储文件的内容。
-spec read_file_info(File, Opts) -> {ok, FileInfo} | {error, Reason} when File :: name_all() | io_device(), Opts :: [file_info_option()], FileInfo :: file_info(), Reason :: posix() | badarg.
检索有关文件的信息。如果成功,则返回 {ok, FileInfo}
,否则返回 {error, Reason}
。
FileInfo
是一个记录 file_info
,在 Kernel 包含文件 file.hrl
中定义。在调用该函数的模块中包含以下指令
-include_lib("kernel/include/file.hrl").
在 atime
、mtime
和 ctime
中返回的时间类型取决于 Opts :: {time, Type}
中设置的时间类型,如下所示
local
- 返回本地时间。universal
- 返回世界标准时间。posix
- 返回自 Unix 时间纪元(即 1970-01-01 00:00 UTC)以来或之前的秒数。
默认值为 {time, local}
。
如果设置了选项 raw
,则不会调用文件服务器,并且仅返回有关本地文件的信息。请注意,这将破坏此模块的原子性保证,因为它可能会与同时调用 write_file_info/1,2
竞争。
当该函数被赋予 I/O 设备而不是文件名时,此选项不起作用。请先使用 raw
模式调用 open/2
以获取文件描述符。
注意
由于文件时间在大多数操作系统上以 POSIX 时间存储,因此使用选项
posix
查询文件信息会更快。
记录 file_info
包含以下字段
size =
non_neg_integer/0
- 文件大小(以字节为单位)。type = device | directory | other | regular
- 文件类型。从 read_link_info/1,2 返回时,也可以包含symlink
。access = read | write | read_write | none
- 当前系统对文件的访问权限。atime =
date_time/0
|
non_neg_integer/0
- 上次读取文件的时间。mtime =
date_time/0
|
non_neg_integer/0
- 上次写入文件的时间。ctime =
date_time/0
|
non_neg_integer/0
- 此时间字段的解释取决于操作系统。在 Unix 上,它是上次更改文件或inode
的时间。在 Windows 中,它是创建时间。mode =
non_neg_integer/0
- 文件权限,为以下位值的总和8#00400
- 读取权限:所有者8#00200
- 写入权限:所有者8#00100
- 执行权限:所有者8#00040
- 读取权限:组8#00020
- 写入权限:组8#00010
- 执行权限:组8#00004
- 读取权限:其他8#00002
- 写入权限:其他8#00001
- 执行权限:其他16#800
- 在执行时设置用户 ID16#400
- 在执行时设置组 ID
在 Unix 平台上,可能会设置上面未列出的其他位。
links =
non_neg_integer/0
- 指向文件的链接数(对于没有链接概念的文件系统,此值始终为 1)。major_device =
non_neg_integer/0
- 标识文件所在的文件系统。在 Windows 中,该数字指示驱动器,如下所示:0 表示 A:,1 表示 B:,依此类推。minor_device =
non_neg_integer/0
- 仅对 Unix 上的字符设备有效。在所有其他情况下,此字段为零。inode =
non_neg_integer/0
- 提供inode
编号。在非 Unix 文件系统上,此字段为零。uid =
non_neg_integer/0
- 指示文件的所有者。在非 Unix 文件系统上,此字段为零。gid =
non_neg_integer/0
- 提供文件所有者所属的组。在非 Unix 文件系统上,此字段为零。
典型的错误原因
eacces
- 缺少文件父目录之一的搜索权限。enoent
- 该文件不存在。enotdir
- 文件名的组件不是目录。在某些平台上,返回enoent
。
-spec read_line(IoDevice) -> {ok, Data} | eof | {error, Reason} when IoDevice :: io_device() | io:device(), Data :: string() | binary(), Reason :: posix() | badarg | terminated | {no_translation, unicode, latin1}.
从 IoDevice
引用的文件中读取一行字节/字符。
行被定义为由换行符 (LF, \n
) 分隔,但任何回车符 (CR, \r
) 后跟换行符也被视为单个 LF 字符(回车符会被静默忽略)。返回的行包括 LF,但不包括任何紧跟 LF 的 CR。此行为与 io:get_line/2
的行为一致。如果到达文件末尾且最后一行没有任何 LF 结尾,则返回没有尾随 LF 的行。
该函数可以用于以 raw
模式打开的文件。但是,如果文件没有指定 {read_ahead, Size}
选项,则在 raw
文件上使用它效率低下。因此,当打开文本文件以进行原始的面向行的读取时,强烈建议组合使用 raw
和 {read_ahead, Size}
。
如果 encoding
设置为除 latin1
以外的其他值,则如果数据包含大于 255 的字符,则 read_line/1
调用将失败,因此当读取此类文件时,应首选 io:get_line/2
。
该函数返回
{ok, Data}
- 返回文件中一行,包括尾随 LF,但 CRLF 序列将被替换为单个 LF(见上文)。如果文件以二进制模式打开,则读取的字节将以二进制形式返回,否则以列表形式返回。
eof
- 如果在读取任何内容之前到达文件末尾,则返回此项。{error, Reason}
- 发生错误。
典型的错误原因
ebadf
- 文件未打开以进行读取。{no_translation, unicode, latin1}
- 该文件使用除latin1
以外的其他encoding
打开,并且文件中的数据无法转换为此函数返回的面向字节的数据。
-spec read_link(Name) -> {ok, Filename} | {error, Reason} when Name :: name_all(), Filename :: filename(), Reason :: posix() | badarg.
如果 Name
指的是不是原始文件名的符号链接,则返回 {ok, Filename}
,否则返回 {error, Reason}
。在不支持符号链接的平台上,返回值是 {error,enotsup}
。
典型的错误原因
einval
-Name
不指向符号链接,或者它指向的文件名不符合预期的编码。enoent
- 该文件不存在。enotsup
- 此平台不支持符号链接。
-spec read_link_all(Name) -> {ok, Filename} | {error, Reason} when Name :: name_all(), Filename :: filename_all(), Reason :: posix() | badarg.
如果 Name
指的是符号链接,则返回 {ok, Filename}
,否则返回 {error, Reason}
。在不支持符号链接的平台上,返回值是 {error,enotsup}
。
请注意,Filename
可以是列表或二进制。
典型的错误原因
einval
-Name
不指向符号链接。enoent
- 该文件不存在。enotsup
- 此平台不支持符号链接。
-spec read_link_info(Name, Opts) -> {ok, FileInfo} | {error, Reason} when Name :: name_all(), Opts :: [file_info_option()], FileInfo :: file_info(), Reason :: posix() | badarg.
与 read_file_info/1,2
的工作方式相同,但如果 Name
是符号链接,则有关该链接的信息将返回到 file_info
记录中,并且记录的 type
字段设置为 symlink
。
如果设置了 raw
选项,则不会调用文件服务器,并且仅返回有关本地文件的信息。请注意,这会破坏此模块的原子性保证,因为它可能与并发调用 write_file_info/1,2
发生冲突。
如果 Name
不是符号链接,则此函数返回与 read_file_info/1
相同的结果。在不支持符号链接的平台上,此函数始终等效于 read_file_info/1
。
-spec rename(Source, Destination) -> ok | {error, Reason} when Source :: name_all(), Destination :: name_all(), Reason :: posix() | badarg.
尝试将文件 Source
重命名为 Destination
。它可以用于在目录之间移动文件(和目录),但仅指定目标是不够的。还必须指定目标文件名。例如,如果 bar
是一个普通文件,foo
和 baz
是目录,则 rename("foo/bar", "baz")
返回错误,但 rename("foo/bar", "baz/bar")
成功。如果成功,则返回 ok
。
注意
在大多数平台上不允许重命名打开的文件(请参见下面的
eacces
)。
典型的错误原因
eacces
- 缺少Source
或Destination
的父目录的读取或写入权限。在某些平台上,如果Source
或Destination
处于打开状态,则会给出此错误。eexist
-Destination
不是空目录。在某些平台上,当Source
和Destination
不是同一类型时也会给出此错误。einval
-Source
是根目录,或者Destination
是Source
的子目录。eisdir
-Destination
是一个目录,但Source
不是。enoent
-Source
不存在。enotdir
-Source
是一个目录,但Destination
不是。exdev
-Source
和Destination
位于不同的文件系统上。
-spec script(Filename) -> {ok, Value} | {error, Reason} when Filename :: name_all(), Value :: term(), Reason :: posix() | badarg | terminated | system_limit | {Line :: integer(), Mod :: module(), Term :: term()}.
从文件中读取并计算以 .
(或 ,
,表达式序列也是一个表达式)分隔的 Erlang 表达式。
返回以下其中一项
{ok, Value}
- 读取并评估该文件。Value
是最后一个表达式的值。{error, atom()}
- 打开文件或读取文件时发生错误。有关典型错误代码的列表,请参阅open/2
。{error, {Line, Mod, Term}}
- 解释文件中的 Erlang 表达式时发生错误。使用format_error/1
将三元素元组转换为错误的英文描述。
Filename
的编码可以通过注释进行设置,如 epp
中所述。
-spec sendfile(Filename, Socket) -> {ok, non_neg_integer()} | {error, inet:posix() | closed | badarg | not_owner} when Filename :: name_all(), Socket :: inet:socket() | socket:socket() | fun((iolist()) -> ok | {error, inet:posix() | closed}).
将文件 Filename
发送到 Socket
。如果成功,则返回 {ok, BytesSent}
,否则返回 {error, Reason}
。
-spec sendfile(RawFile, Socket, Offset, Bytes, Opts) -> {ok, non_neg_integer()} | {error, inet:posix() | closed | badarg | not_owner} when RawFile :: fd(), Socket :: inet:socket() | socket:socket() | fun((iolist()) -> ok | {error, inet:posix() | closed}), Offset :: non_neg_integer(), Bytes :: non_neg_integer(), Opts :: [sendfile_option()].
将从 RawFile
引用的文件中,从 Offset
开始的 Bytes
发送到 Socket
。如果成功,则返回 {ok, BytesSent}
,否则返回 {error, Reason}
。如果 Bytes
设置为 0
,则会发送指定 Offset
之后的所有数据。
使用的文件必须使用 raw
标志打开,并且调用 sendfile
的进程必须是套接字的控制进程。请参阅 gen_tcp:controlling_process/2
或模块 socket
的 level otp
套接字选项 controlling_process
。
如果使用的操作系统不支持非阻塞 sendfile
,则会使用 Erlang 回退,该回退使用 read/2
和 gen_tcp:send/2
。
选项列表可以包含以下选项:
chunk_size
- Erlang 回退用来发送数据的块大小。如果使用回退,请将其设置为一个可以舒适地容纳在系统内存中的值。默认值为 20 MB。
-spec set_cwd(Dir) -> ok | {error, Reason} when Dir :: name() | EncodedBinary, EncodedBinary :: binary(), Reason :: posix() | badarg | no_translation.
将文件服务器的当前工作目录设置为 Dir
。如果成功,则返回 ok
。
模块 file
中的函数通常将二进制文件视为原始文件名,也就是说,即使二进制文件的编码与 native_name_encoding()
不一致,也会“按原样”传递它们。但是,此函数期望二进制文件根据 native_name_encoding/0
返回的值进行编码。
典型的错误原因是:
enoent
- 该目录不存在。enotdir
-Dir
的组件不是目录。在某些平台上,返回enoent
。eacces
- 缺少目录或其父目录之一的权限。badarg
-Dir
具有不正确的类型,例如元组。no_translation
-Dir
是一个使用 ISO-latin-1 编码的字符的binary/0
,而 VM 正在使用 unicode 文件名编码进行操作。
警告
在未来的版本中,参数
Dir
的错误类型可能会生成异常。
-spec sync(IoDevice) -> ok | {error, Reason} when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.
确保操作系统(而不是 Erlang 运行时系统)保留的任何缓冲区都写入磁盘。在某些平台上,此函数可能不起作用。
一个典型的错误原因是
enospc
- 没有足够的空间来写入文件。
-spec truncate(IoDevice) -> ok | {error, Reason} when IoDevice :: io_device(), Reason :: posix() | badarg | terminated.
在当前位置截断 IoDevice
引用的文件。如果成功,则返回 ok
,否则返回 {error, Reason}
。
-spec write(IoDevice, Bytes) -> ok | {error, Reason} when IoDevice :: io_device() | io:device(), Bytes :: iodata(), Reason :: posix() | badarg | terminated.
将 Bytes
写入 IoDevice
引用的文件。此函数是写入以 raw
模式打开的文件的唯一方法(尽管它也适用于正常打开的文件)。如果成功,则返回 ok
,否则返回 {error, Reason}
。
如果使用除 latin1
以外的其他 encoding
打开文件,则写入的每个字节都可能导致向文件写入多个字节,因为字节范围 0..255 可以表示一个到四个字节之间的任何内容,具体取决于值和 UTF 编码类型。如果要将 unicode:chardata/0
写入 IoDevice
,则应改用 io:put_chars/2
。
典型的错误原因
ebadf
- 文件未打开以进行写入。enospc
- 设备上没有剩余空间。
-spec write_file(Filename, Bytes) -> ok | {error, Reason} when Filename :: name_all(), Bytes :: iodata(), Reason :: posix() | badarg | terminated | system_limit.
将 iodata
项 Bytes
的内容写入文件 Filename
。如果文件不存在,则创建该文件。如果文件存在,则会覆盖先前的内容。如果成功,则返回 ok
,否则返回 {error, Reason}
。
典型的错误原因
enoent
- 文件名的组件不存在。enotdir
- 文件名的组件不是目录。在某些平台上,返回enoent
。enospc
- 设备上没有剩余空间。eacces
- 缺少写入文件或搜索其父目录之一的权限。eisdir
- 指定的文件是一个目录。
-spec write_file(Filename, Bytes, Modes) -> ok | {error, Reason} when Filename :: name_all(), Bytes :: iodata(), Modes :: [mode()], Reason :: posix() | badarg | terminated | system_limit.
与 write_file/2
相同,但采用第三个参数 Modes
(可能的模式列表),请参阅 open/2
。模式标志 binary
和 write
是隐式的,因此不应使用它们。
-spec write_file_info(Filename, FileInfo, Opts) -> ok | {error, Reason} when Filename :: name_all(), Opts :: [file_info_option()], FileInfo :: file_info(), Reason :: posix() | badarg.
更改文件信息。如果成功,则返回 ok
,否则返回 {error, Reason}
。
FileInfo
是一个记录 file_info
,在 Kernel 包含文件 file.hrl
中定义。在调用该函数的模块中包含以下指令
-include_lib("kernel/include/file.hrl").
在 atime
、mtime
和 ctime
中设置的时间类型取决于 Opts :: {time, Type}
中设置的时间类型,如下所示:
local
- 将设置的时间解释为本地时间。universal
- 将其解释为世界标准时间。posix
- 必须是自 Unix 时间纪元(即 1970-01-01 00:00 UTC)以来或之前的秒数。
默认值为 {time, local}
。
如果设置了 raw
选项,则不会调用文件服务器,并且仅返回有关本地文件的信息。
如果指定了以下字段,则使用该记录中的以下字段:
atime =
date_time/0
|
non_neg_integer/0
- 上次读取文件的时间。mtime =
date_time/0
|
non_neg_integer/0
- 上次写入文件的时间。ctime =
date_time/0
|
non_neg_integer/0
- 在 Unix 上,为此字段指定的任何值都将被忽略(文件的“ctime”将设置为当前时间)。在 Windows 上,此字段是要为文件设置的新创建时间。mode =
non_neg_integer/0
- 文件权限,为以下位值的总和8#00400
- 读取权限:所有者8#00200
- 写入权限:所有者8#00100
- 执行权限:所有者8#00040
- 读取权限:组8#00020
- 写入权限:组8#00010
- 执行权限:组8#00004
- 读取权限:其他8#00002
- 写入权限:其他8#00001
- 执行权限:其他16#800
- 执行时设置用户 ID16#400
- 执行时设置组 ID
在 Unix 平台上,可能会设置上面未列出的其他位。
uid =
非负整数
- 指示文件所有者。在非 Unix 文件系统中被忽略。gid =
非负整数
- 给出文件所有者所属的组。在非 Unix 文件系统中被忽略。
典型的错误原因
eacces
- 缺少文件父目录之一的搜索权限。enoent
- 该文件不存在。enotdir
- 文件名的组件不是目录。在某些平台上,返回enoent
。