文件 | File
文件(File)
此模块包含操纵文件的功能。
其中一些函数是低级的,允许用户与文件或IO设备交互,如开/ 2,,,复制/ 3还有其他人。该模块还提供了更高级别的函数,这些函数可以处理文件名,并基于UNIX变体进行命名。例如,可以通过CP /3并通过以下方式递归删除文件和目录rm_rf/1 ...
在这个模块中赋予函数的路径可以是相对于当前工作目录(由返回的File.cwd/0
)或绝对路径。像shell这样的约定~
不会自动扩展。要使用类似的路径~/Downloads
,可以使用Path.expand/1
或Path.expand/2
将路径展开为绝对路径。
编码
为了写入和读取文件,必须使用IO模块中的功能。 默认情况下,文件以二进制模式打开,这需要函数IO.binread / 2和IO.binwrite / 2与文件进行交互。 开发人员在打开文件时可能会传递:utf8作为选项,那么必须使用较慢的IO.read/2和IO.write / 2函数,因为它们负责进行正确的转换并提供适当的数据保证。
请注意,在Elixir中以charlists形式提供的文件名始终被视为UTF-8。特别是,我们期望shell和操作系统被配置为使用UTF-8编码。二进制文件名被视为原始文件,并按原样传递给操作系统。
API
这个模块中的大部分函数返回:ok或{:ok,result},否则返回{:error,reason}。 这些函数也有一个以!结尾的变体! 它在成功的情况下返回结果(而不是{:ok,result}元组),或者在失败的情况下引发异常。 例如:
File.read("hello.txt")
#=> {:ok, "World"}
File.read("invalid.txt")
#=> {:error, :enoent}
File.read!("hello.txt")
#=> "World"
File.read!("invalid.txt")
#=> raises File.Error
一般来说,如果文件不存在,开发人员应该使用前者以防他们想要做出反应。当开发者期望他们的软件在文件不能被读取的情况下失败时(即,它实际上是一个例外),应该使用后者。
进程和原始文件
每次打开文件时,Elixir都会产生一个新的进程。写入文件相当于将消息发送到写入文件描述符的进程。
这意味着文件可以在节点之间传递,并且消息传递保证它们可以写入网络中的同一个文件。
但是,您可能并不总是想为这种抽象付出代价。 在这种情况下,文件可以在原始模式下打开。 选项:read_ahead和:delayed_write在对大文件进行操作或在紧密循环中处理文件时也很有用。
检查:file.open/2
有关这些选项和其他性能注意事项的更多信息。
摘要
类型
io_device()mode()posix()stat_options()
功能
cd(path)
设置当前工作目录。
cd!(path)
cd/1
与之相同,但如果失败则引发异常
cd!(path, function)
将当前目录更改为给定path
,执行给定函数,然后返回到前一个路径,无论是否存在异常
chgrp(path, gid)
更改给定文件的组ID为gid的组。 返回:确定成功,或者失败时返回{:error, reason}
chgrp!(path,gid)
同chgrp/2
,但在失败的情况下会引发异常。否则返回:ok
chmod(path, mode)
更改mode
为某一给定file
chmod!(path, mode)
同chmod/2
,但在失败的情况下会引发异常。否则返回:ok
chown(path, uid)
更改给定文件的用户ID uid给出的所有者。 返回:确定成功,或者失败时返回{:error, reason}
chown!(path, uid)
同chown/2
,但在失败的情况下会引发异常。否则返回:ok
close(io_device)
关闭由io_device引用的文件。 它主要返回:ok,除了一些严重的错误,如内存不足
copy(source, destination, bytes_count \ :infinity)
复制内容source
到destination
copy!(source, destination, bytes_count \ :infinity)
与复制/ 3相同,但如果失败则引发File.CopyError。 否则返回bytes_copied
cp(source, destination, callback \ fn _, _ -> true end)
复制source
到destination
保持其模式
cp!(source, destination, callback \ fn _, _ -> true end)
与cp / 3相同,但如果失败则引发File.CopyError。 否则返回:ok
cp_r(source, destination, callback \ fn _, _ -> true end)
将源中的内容复制到目标
cp_r!(source, destination, callback \ fn _, _ -> true end)
与cp_r / 3相同,但如果失败则引发File.CopyError。 否则返回复制文件的列表
CWD()
获取当前工作目录。
CWD!()
同cwd/0
,但如果异常失败,则会引发异常。
DIR?(path)
如果给定路径是目录,则返回true
exists?(path)
如果给定路径存在,返回true。
它可以是常规文件,目录,套接字,符号链接,命名管道或设备文件
ln(existing, new)
创建一个硬链接new
到文件existing
ln!(existing, new)
同ln/2
但是,如果异常失败,则会引发异常。
ln_s(existing, new)
创建new
文件或目录的符号链接existing
ln_s!(existing, new)
同ln_s/2
但是,如果异常失败,则会引发异常。
ls(path\“。”)
返回给定目录中的文件列表。
ls!(path \ ".")
与ls / 1相同,但在发生错误时引发File.Error
lstat(path, opts \ [])
返回有关路径的信息。 如果该文件是符号链接,则将该类型设置为:符号链接并为该链接返回一个File.Stat结构体。 对于任何其他文件,返回与stat / 2完全相同的值
lstat!(path, opts \ [])
与lstat / 2相同,但直接返回File.Stat结构,或者在返回错误时引发File.Error
mkdir(path)
尝试创建目录路径。 没有创建缺少父目录。 返回:如果成功,则返回OK;如果发生错误,则返回{:error, reason}
mkdir!(path)
同mkdir/1
,但在失败的情况下会引发异常。否则返回:ok
mkdir_p(path)
尝试创建目录路径。 缺少父目录被创建。 返回:如果成功,则返回OK;如果发生错误,则返回 {:error, reason}
mkdir_p!(path)
同mkdir_p/1
,但在失败的情况下会引发异常。否则返回:ok
open(path, modes_or_function \ [])
打开给定的path
open(path, modes, function)
类似于open/2
但期望一个函数作为最后一个参数
open!(path, modes_or_function \ [])
类似于open/2
但是,如果无法打开文件,则会引发错误。
open!(path, modes, function)
类似于open/3
但是,如果无法打开文件,则会引发错误。
read(path)
返回{:ok, binary}
,其中binary
是包含内容path
或{:error, reason}
发生错误的二进制数据对象
read!(path)
返回具有给定文件名内容的二进制文件,如果发生错误,则返回File.Error
read_link(path)
读取符号链接path
read_link!(path)
与read_link / 1相同,但直接返回目标或在返回错误时抛出File.Error
regular?(path)
如果路径是常规文件,则返回true
rename(source, destination)
重命名source
档案到destination
档案。它可用于在目录之间移动文件%28和目录%29。如果移动文件,则必须完全指定destination
文件名,仅指定其目录是不够的。
rm(path)
尝试删除文件path
rm!(path)
同rm/1
,但在失败的情况下会引发异常。否则返回:ok
rm_rf(path)
在给定的位置递归地移除文件和目录path
。符号链接不会被遵循,只是被删除,不存在的文件会被忽略(即不会使这个函数失败)
rm_rf!(path)
与rm_rf / 1相同,但在出现故障时引发File.Error,否则将删除文件或目录的列表
rmdir(path)
尝试删除路径中的目录。 返回:如果成功,则返回OK;如果发生错误,则返回{:错误,原因}
rmdir!(path)
同rmdir/1
,但在失败的情况下会引发异常。否则返回:ok
stat(path, opts \ [])
返回有关的信息path
。如果它存在,它将返回一个{:ok, info}
元组,其中info是一个File.Stat
结构。返回{:error, reason}
与read/1
发生故障一样的原因
stat!(path, opts \ [])
与stat / 2相同,但直接返回File.Stat,如果返回错误则抛出File.Error
tream!(path, modes \ [], line_or_bytes \ :line)
使用给定的模式返回给定路径的File.Stream
touch(path, time \ :calendar.universal_time())
更新给定文件的修改时间(mtime)和访问时间(atime)
touch!(path, time \ :calendar.universal_time())
与touch / 2相同,但如果失败则引发异常
write(path, content, modes \ [])
写content
到文件path
write!(path, content, modes \ [])
与write/ 3相同,但如果失败则引发异常,否则返回:OK
write_stat(path, stat, opts \ [])
写入给定File.Stat
返回到给定路径的文件系统。回报:ok
或{:error, reason}
write_stat!(path, stat, opts \ [])
与write_stat / 3相同,但如果失败则引发异常。 返回:否则返回
类型
io_device()
io_device() :: :file.io_device
mode()
mode ::
:append |
:binary |
:charlist |
:compressed |
:delayed_write |
:exclusive |
:raw |
:read |
:read_ahead |
:sync |
:utf8 |
:write |
{:encoding, :latin1 | :unicode | :utf8 | :utf16 | :utf32 | {:utf16, :big | :little} | {:utf32, :big | :little}} |
{:read_ahead, pos_integer} |
{:delayed_write, non_neg_integer, non_neg_integer}
posix()
posix() :: :file.posix
stat_options()
stat_options() :: [{:time, :local | :universal | :posix}]
功能
CD(路径)
cd(Path.t) :: :ok | {:error, posix}
设置当前工作目录。
如果成功则返回:ok
,否则为{:error, reason}
。
CD!(路径)
cd!(Path.t) :: :ok | no_return
同cd/1
,但如果失败,则会引发异常。
cd!(路径,功能)
cd!(Path.t, (() -> res)) :: res when res: var
将当前目录更改为path
,执行给定的函数,然后不管是否存在异常,都返回到前面的路径。
如果检索或更改当前目录失败,则引发错误。
chgrp(路径,gid)
chgrp(Path.t, non_neg_integer) :: :ok | {:error, posix}
更改给定文件的组ID为gid的组。 返回:确定成功,或者失败时返回{:error, reason}
chgrp!(路径,gid)
chgrp!(Path.t, non_neg_integer) :: :ok | no_return
同chgrp/2
,但在失败的情况下会引发异常。否则返回:ok
...
chmod(路径,模式)
chmod(Path.t, non_neg_integer) :: :ok | {:error, posix}
更改mode
为某一给定file
...
成功时返回::ok,或者失败时返回{:error, reason}
权限
文件权限是通过将以下八进制标志相加而指定的:
0o400
-阅读许可:所有者
0o200
-书写许可:所有者
0o100
-执行许可:所有者
0o040
-阅读许可:团体
0o020
-书写许可:组
0o010
-执行许可:组
0o004
-阅读许可:其他
0o002
-书写许可:其他
0o001
- 执行权限:other
:time
- 配置文件时间戳的返回方式
值:time
可以是:
:universal
-{date, time}
以UTC形式返回一个元组(默认)
:local
-{date, time}
使用机器时间返回一个元组
:posix
- 从时代开始,以整数秒为单位返回时间
lstat!(path, opts \ [])
lstat!(Path.t, stat_options) :: File.Stat.t | no_return
与lstat / 2相同,但直接返回File.Stat结构,或者在返回错误时引发File.Error。
mkdir(path)
mkdir(Path.t) :: :ok | {:error, posix}
尝试创建目录路径。 没有创建缺少父目录。 返回:如果成功,则返回OK;如果发生错误,则返回{:错误,原因}。
典型的错误原因是:
:eacces
的父目录缺少搜索或写入权限。path
:eexist
- 已经有一个名为path
的文件或目录
:enoent
---path
不存在
:enospc
-设备上没有空间
:enotdir
---path
不是目录;在某些平台上,:enoent
将被返回。
mkdir!(path)
mkdir!(Path.t) :: :ok | no_return
同mkdir/1
,但在失败的情况下会引发异常。否则返回:ok
...
mkdir_p(path)
mkdir_p(Path.t) :: :ok | {:error, posix}
尝试创建目录路径。 缺少父目录被创建。 返回:如果成功,则返回OK;如果发生错误,则返回{:error, reason}
典型的错误原因是:
- :eacces - 缺少路径父目录的搜索或写入权限
:enospc
-设备上没有空间
:enotdir
---path
不是目录
mkdir_p!(path)
mkdir_p!(Path.t) :: :ok | no_return
与mkdir_p/1
相同,但在发生故障时引发异常。否则:ok
。
open(path, modes_or_function \ [])
open(Path.t, (io_device -> res)) ::
{:ok, res} |
{:error, posix} when res: var
open(Path.t, [mode | :ram]) ::
{:ok, io_device} |
{:error, posix}
打开给定的path
。
为了写入和读取文件,必须使用IO
模块中的功能。默认情况下,文件以:binary
模式打开,这需要功能IO.binread/2
并IO.binwrite/2
与文件进行交互。开发人员可以:utf8
在打开文件时作为选项通过,然后可以使用所有其他功能IO
,因为它们直接与Unicode数据一起工作。
modes_or_function
可以是模式列表或功能列表。如果它是一个列表,它被认为是一个模式列表(下面有文档说明)。如果它是一个函数,那么它就等同于调用open(path, [], modes_or_function)
。有关open/3
此功能的更多信息,请参阅文档。
允许的模式:
:binary
- 以二进制模式打开文件,禁用unicode序列的特殊处理(默认模式)。
:read
- 必须存在的文件已打开供阅读。
:write
- 文件被打开以供写入。如果它不存在,则创建它。如果该文件确实存在,并且如果写入未与读取结合,则该文件将被截断。
:append
-文件将被打开,以便写入,如果文件不存在,将创建该文件。每次对以追加方式打开的文件的写操作都将在文件的末尾进行。
:exclusive
-当文件打开以便写入时,如果文件不存在,则创建该文件。如果文件存在,打开将返回{:error, :eexist}
...
:charlist
-当这个词出现时,文件上的读取操作将返回字符列表,而不是二进制文件。
:compressed
-使读取或写入gzip压缩文件成为可能。 压缩选项必须与读或写相结合,但不能两者兼而有之。请注意,使用stat/1
将很可能与可从压缩文件中读取的字节数不匹配。
:utf8
-此选项表示数据如何实际存储在磁盘文件中,并使该文件执行字符与UTF-8之间的自动转换。
如果数据以无法转换为UTF-8的格式发送到文件,或者由返回无法处理数据字符范围的格式的数据的函数读取,则会发生错误并关闭文件。
:delayed_write
,:raw
,:ram
,:read_ahead
,:sync
,{:encoding, ...}
,{:read_ahead, pos_integer}
,{:delayed_write, non_neg_integer, non_neg_integer}
-有关这些选项的详细信息,请参阅:file.open/2
。这个函数返回:
{:ok, io_device}
-文件已按请求模式打开。
io_device
实际上是处理文件的进程的PID。此进程链接到最初打开文件的进程。如果任何进程的io_device
是链接终止,文件将被关闭,进程本身将被终止。
一个io_device
从该调用返回可被用作一个参数的IO
模块的功能。
{:error, reason}
- 文件无法打开。
:enoent
-档案不存在
:eacces
-缺少读取文件或搜索父目录之一的权限
:eisdir
-命名文件是一个目录
:enotdir
-文件名的一个组件不是目录;在某些平台上,:enoent
将被返回。
:enomem
-内存不足,无法存储文件的内容
你可以用:file.format_error/1
若要获得错误的描述性字符串,请执行以下操作。
read!(path)
read!(Path.t) :: binary | no_return
返回具有给定文件名内容的二进制文件,如果发生错误,则返回File.Error。
read_link(path)
read_link(Path.t) :: {:ok, binary} | {:error, posix}
阅读中的符号链接path
。
如果path
存在并且是符号链接,则返回{:ok, target}
,否则返回{:error, reason}
。
有关更多详情,请参阅:file.read_link/1
。
典型的错误原因是:
:einval
-路径不是符号链接
:enoent
-路径不存在
:enotsup
-当前平台不支持符号链接
read_link!(path)
read_link!(Path.t) :: binary | no_return
同read_link/1
而是直接返回目标或抛出File.Error
,如果返回错误。
regular?(path)
regular?(Path.t) :: boolean
如果路径是常规文件,则返回true。
此函数遵循符号链接,因此如果符号链接指向常规文件,则被返回true
。
实例
File.regular? __ENV__.file #=> true
rename(source, destination)
rename(Path.t, Path.t) :: :ok | {:error, posix}
将source
文件重命名为destination
文件。它可以用来在目录之间移动文件(和目录)。如果移动一个文件,你必须完全指定destination
文件名,仅仅指定它的目录是不够的。
如果成功则返回ok
,否则:
返回{:error, reason}
。
注意:Unix系统中的命令mv的行为有所不同,具体取决于源是文件还是目标是现有目录。 我们选择明确禁止这种行为。
实例
# Rename file "a.txt" to "b.txt"
File.rename "a.txt", "b.txt"
# Rename directory "samples" to "tmp"
File.rename "samples", "tmp"
rm(path)
rm(Path.t) :: :ok | {:error, posix}
试图删除文件path
。
如果成功返回:ok
,或发生错误{:error, reason}
。
注意,即使在只读模式下,文件也被删除.
典型的错误原因是:
:enoent
-档案不存在
:eacces
-缺少文件或其父母之一的许可
:eperm
-文件是一个目录,用户不是超级用户
:enotdir
-文件名的一个组件不是目录;在某些平台上,:enoent
将被返回。
:einval
-文件名的类型不正确,例如元组
实例
File.rm("file.txt")
#=> :ok
File.rm("tmp_dir/")
#=> {:error, :eperm}
rm!(path)
rm!(Path.t) :: :ok | no_return
与rm/1
相同,但在发生故障时引发异常。否则:ok
。
rm_rf(path)
rm_rf(Path.t) :: {:ok, [binary]} | {:error, posix, binary}
在给定的位置递归地移除文件和目录path
。符号链接没有被遵循,只是被删除,不存在的文件被忽略(即不会使这个函数失败)。
返回{:ok, files_and_directories}
的所有文件,并在没有特定的顺序删除目录,否则{:error, reason, file}
。
实例
File.rm_rf "samples"
#=> {:ok, ["samples", "samples/1.txt"]}
File.rm_rf "unknown"
#=> {:ok, []}
rm_rf!(path)
rm_rf!(Path.t) :: [binary] | no_return
与rm_rf/1
失败时相同但会提高File.Error
,否则删除文件或目录的列表。
rmdir(path)
rmdir(Path.t) :: :ok | {:error, posix}
尝试删除目录path
。如果成功返回:ok
,或发生错误返回{:error, reason}
。
实例
File.rmdir('tmp_dir')
#=> :ok
File.rmdir('file.txt')
#=> {:error, :enotdir}
rmdir!(path)
rmdir!(Path.t) :: :ok | {:error, posix}
与rmdir/1
相同,但在发生故障时引发异常。否则:ok
。
stat(path, opts \ [])
stat(Path.t, stat_options) ::
{:ok, File.Stat.t} |
{:error, posix}
返回有关的信息path
。如果它存在,它将返回一个{:ok, info}
元组,其中info是一个File.Stat
结构。返回{:error, reason}
与read/1
发生故障一样的原因。
备选方案
已接受的备选方案如下:
:time
-配置文件时间戳的返回方式的值:time
可以是:
:universal
-{date, time}
以UTC形式返回一个元组(默认)
:local
-{date, time}
使用与机器相同的时区返回一个元组
:posix
- 以整数秒为单位返回时间
stat!(path, opts \ [])
stat!(Path.t, stat_options) :: File.Stat.t | no_return
与stat/2
相同,但返回File.Stat
直接或抛出File.Error
,如果返回错误。
stream!(path, modes \ [], line_or_bytes \ :line)
返回File.Stream
给定给定path
的给定值modes
。
流实现了这两个Enumerable
和Collectable
协议,这意味着它可以用于读写。
该line_or_bytes
参数配置如何流时,通过读取文件:line
(默认)或字节的给定数。
由于相同的原因,操作流可能会失败File.open!/2
。请注意,每次开始流式处理时,文件都会自动打开。没有必要传递:read
和:write
模式,因为那些是由Elixir自动设置的。
原始文件
由于Elixir控制流文件何时打开,因此基础设备无法共享,因此出于性能原因以原始模式打开文件很方便。因此,除非指定了编码,否则Elixir 将
:raw
使用该:read_ahead
选项以模式打开流。这意味着流入文件的任何数据必须转换为t:iodata/0
类型。如果您传入[:utf8]
模式参数,则基础流将
使用IO.write/2
该String.Chars
协议并转换数据。见IO.binwrite/2
和IO.write/2
。
如果流意图在严格循环下写入,则可以考虑传递:delayed_write选项。
字节顺序标记
如果传入:trim_bom
modes参数,则从文件读取时,流将修剪UTF-8,UTF-16和UTF-32字节顺序标记。
实例
# Read in 2048 byte chunks rather than lines
File.stream!("./test/test.data", [], 2048)
#=> %File.Stream{line_or_bytes: 2048, modes: [:raw, :read_ahead, :binary],
#=> path: "./test/test.data", raw: true}
查看Stream.run/1
流式传输到文件的示例。
touch(path, time \ :calendar.universal_time())
touch(Path.t, :calendar.datetime) :: :ok | {:error, posix}
更新给定文件的修改时间(mtime)和访问时间(atime)。
如果该文件不存在,则会创建该文件。需要UTC的日期时间。
touch!(path, time \ :calendar.universal_time())
touch!(Path.t, :calendar.datetime) :: :ok | no_return
相同,touch/2
但如果失败则会引发异常。
否则返回:ok
。需要UTC的日期时间。
write(path, content, modes \ [])
write(Path.t, iodata, [mode]) :: :ok | {:error, posix}
将内容写入文件路径。
如果该文件不存在,则会创建该文件。如果存在,则先前的内容被覆盖。如果成功返回:ok
,或{:error, reason}
发生错误。
content
必须是iodata
(一个字节或二进制的列表)。设置此功能的编码不起作用。
警告:
每次调用此函数时,都会打开一个文件描述符并产生一个新的进程以写入文件。因为这个原因,如果你在循环中进行多次写操作,通过打开文件File.open/2
并使用函数IO
写入文件将比多次调用该函数产生更好的性能。
典型的错误原因是:
:enoent
-不存在文件名的组件
:enotdir
-文件名的一个组件不是目录;在某些平台上,:enoent
将被返回。
:enospc
-设备上没有空间
:eacces
-缺少写入文件或搜索父目录之一的权限
:eisdir
-命名文件是一个目录
检查File.open/2
其他可用选项。
write!(path, content, modes \ [])
write!(Path.t, iodata, [mode]) :: :ok | no_return
与写入/ 3相同,但如果失败则引发异常,否则返回:OK。
write_stat(path, stat, opts \ [])
write_stat(Path.t, File.Stat.t, stat_options) ::
:ok |
{:error, posix}
将给定的File.Stat
回写入给定路径的文件系统。返回:ok
或{:error, reason}
。
write_stat!(path, stat, opts \ [])
write_stat!(Path.t, File.Stat.t, stat_options) ::
:ok |
no_return
相同,write_stat/3
但如果失败则会引发异常。否则返回:ok
。