在线文档教程

文件 | File

文件(File)

此模块包含操纵文件的功能。

其中一些函数是低级的,允许用户与文件或IO设备交互,如开/ 2,,,复制/ 3还有其他人。该模块还提供了更高级别的函数,这些函数可以处理文件名,并基于UNIX变体进行命名。例如,可以通过CP /3并通过以下方式递归删除文件和目录rm_rf/1 ...

在这个模块中赋予函数的路径可以是相对于当前工作目录(由返回的File.cwd/0)或绝对路径。像shell这样的约定~不会自动扩展。要使用类似的路径~/Downloads,可以使用Path.expand/1Path.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)

复制内容sourcedestination

copy!(source, destination, bytes_count \ :infinity)

与复制/ 3相同,但如果失败则引发File.CopyError。 否则返回bytes_copied

cp(source, destination, callback \ fn _, _ -> true end)

复制sourcedestination保持其模式

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/2IO.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

流实现了这两个EnumerableCollectable协议,这意味着它可以用于读写。

line_or_bytes参数配置如何流时,通过读取文件:line(默认)或字节的给定数。

由于相同的原因,操作流可能会失败File.open!/2。请注意,每次开始流式处理时,文件都会自动打开。没有必要传递:read:write模式,因为那些是由Elixir自动设置的。

原始文件

由于Elixir控制流文件何时打开,因此基础设备无法共享,因此出于性能原因以原始模式打开文件很方便。因此,除非指定了编码,否则Elixir :raw使用该:read_ahead选项以模式打开流。这意味着流入文件的任何数据必须转换为t:iodata/0类型。如果您传入[:utf8]模式参数,则基础流使用IO.write/2String.Chars协议并转换数据。见IO.binwrite/2IO.write/2

如果流意图在严格循环下写入,则可以考虑传递:delayed_write选项。

字节顺序标记

如果传入:trim_bommodes参数,则从文件读取时,流将修剪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