View Source File (Elixir v1.13.0)
This module contains functions to manipulate files.
Some of those functions are low-level, allowing the user
to interact with files or IO devices, like open/2
,
copy/3
and others. This module also provides higher
level functions that work with filenames and have their naming
based on Unix variants. For example, one can copy a file
via cp/3
and remove files and directories recursively
via rm_rf/1
.
Paths given to functions in this module can be either relative to the
current working directory (as returned by File.cwd/0
), or absolute
paths. Shell conventions like ~
are not expanded automatically.
To use paths like ~/Downloads
, you can use Path.expand/1
or
Path.expand/2
to expand your path to an absolute path.
Encoding
In order to write and read files, one must use the functions
in the IO
module. By default, a file is opened in binary mode,
which requires the functions IO.binread/2
and IO.binwrite/2
to interact with the file. A developer may pass :utf8
as an
option when opening the file, then the slower IO.read/2
and
IO.write/2
functions must be used as they are responsible for
doing the proper conversions and providing the proper data guarantees.
Note that filenames when given as charlists in Elixir are always treated as UTF-8. In particular, we expect that the shell and the operating system are configured to use UTF-8 encoding. Binary filenames are considered raw and passed to the operating system as is.
API
Most of the functions in this module return :ok
or
{:ok, result}
in case of success, {:error, reason}
otherwise. Those functions also have a variant
that ends with !
which returns the result (instead of the
{:ok, result}
tuple) in case of success or raises an
exception in case it fails. For example:
File.read("hello.txt")
#=> {:ok, "World"}
File.read("invalid.txt")
#=> {:error, :enoent}
File.read!("hello.txt")
#=> "World"
File.read!("invalid.txt")
#=> raises File.Error
In general, a developer should use the former in case they want to react if the file does not exist. The latter should be used when the developer expects their software to fail in case the file cannot be read (i.e. it is literally an exception).
Processes and raw files
Every time a file is opened, Elixir spawns a new process. Writing to a file is equivalent to sending messages to the process that writes to the file descriptor.
This means files can be passed between nodes and message passing guarantees they can write to the same file in a network.
However, you may not always want to pay the price for this abstraction.
In such cases, a file can be opened in :raw
mode. The options :read_ahead
and :delayed_write
are also useful when operating on large files or
working with files in tight loops.
Check :file.open/2
for more information about such options and
other performance considerations.
Link to this section Summary
Functions
Sets the current working directory.
The same as cd/1
, but raises a File.Error
exception if it fails.
Changes the current directory to the given path
,
executes the given function and then reverts back
to the previous path regardless of whether there is an exception.
Changes the group given by the group ID gid
for a given file
. Returns :ok
on success, or
{:error, reason}
on failure.
Same as chgrp/2
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Changes the mode
for a given file
.
Same as chmod/2
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Changes the owner given by the user ID uid
for a given file
. Returns :ok
on success,
or {:error, reason}
on failure.
Same as chown/2
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Closes the file referenced by io_device
. It mostly returns :ok
, except
for some severe errors such as out of memory.
Copies the contents of source
to destination
.
The same as copy/3
but raises a File.CopyError
exception if it fails.
Returns the bytes_copied
otherwise.
Copies the contents of source_file
to destination_file
preserving its modes.
The same as cp/3
, but raises a File.CopyError
exception if it fails.
Returns :ok
otherwise.
Copies the contents in source
to destination
recursively, maintaining the
source directory structure and modes.
The same as cp_r/3
, but raises a File.CopyError
exception if it fails.
Returns the list of copied files otherwise.
Gets the current working directory.
The same as cwd/0
, but raises a File.Error
exception if it fails.
Returns true
if the given path is a directory.
Returns true
if the given path exists.
Creates a hard link new
to the file existing
.
Same as ln/2
but raises a File.LinkError
exception if it fails.
Returns :ok
otherwise.
Creates a symbolic link new
to the file or directory existing
.
Same as ln_s/2
but raises a File.LinkError
exception if it fails.
Returns :ok
otherwise.
Returns the list of files in the given directory.
The same as ls/1
but raises a File.Error
exception in case of an error.
Same as lstat/2
but returns the File.Stat
struct directly,
or raises a File.Error
exception if an error is returned.
Tries to create the directory path
.
Same as mkdir/1
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Tries to create the directory path
.
Same as mkdir_p/1
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Opens the given path
.
Similar to open/2
but expects a function as its last argument.
Similar to open/2
but raises a File.Error
exception if the file
could not be opened. Returns the IO device otherwise.
Similar to open/3
but raises a File.Error
exception if the file
could not be opened.
Returns {:ok, binary}
, where binary
is a binary data object that contains the contents
of path
, or {:error, reason}
if an error occurs.
Returns a binary with the contents of the given filename,
or raises a File.Error
exception if an error occurs.
Reads the symbolic link at path
.
Same as read_link/1
but returns the target directly,
or raises a File.Error
exception if an error is returned.
Returns true
if the path is a regular file.
Renames the source
file to destination
file. It can be used to move files
(and directories) between directories. If moving a file, you must fully
specify the destination
filename, it is not sufficient to simply specify
its directory.
The same as rename/2
but raises a File.RenameError
exception if it fails.
Returns :ok
otherwise.
Tries to delete the file path
.
Same as rm/1
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Removes files and directories recursively at the given path
.
Symlinks are not followed but simply removed, non-existing
files are simply ignored (i.e. doesn't make this function fail).
Same as rm_rf/1
but raises a File.Error
exception in case of failures,
otherwise the list of files or directories removed.
Tries to delete the dir at path
.
Same as rmdir/1
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Same as stat/2
but returns the File.Stat
directly,
or raises a File.Error
exception if an error is returned.
Returns a File.Stream
for the given path
with the given modes
.
Updates modification time (mtime) and access time (atime) of the given file.
Same as touch/2
but raises a File.Error
exception if it fails.
Returns :ok
otherwise.
Writes content
to the file path
.
Same as write/3
but raises a File.Error
exception if it fails.
Returns :ok
otherwise.
Writes the given File.Stat
back to the file system at the given
path. Returns :ok
or {:error, reason}
.
Same as write_stat/3
but raises a File.Error
exception if it fails.
Returns :ok
otherwise.
Link to this section Types
@type encoding_mode() ::
:utf8
| {:encoding,
:latin1
| :unicode
| :utf8
| :utf16
| :utf32
| {:utf16, :big | :little}
| {:utf32, :big | :little}}
@type erlang_time() :: {{year :: non_neg_integer(), month :: 1..12, day :: 1..31}, {hour :: 0..23, minute :: 0..59, second :: 0..59}}
@type io_device() :: :file.io_device()
@type mode() :: :append | :binary | :charlist | :compressed | :delayed_write | :exclusive | :raw | :read | :read_ahead | :sync | :write | {:read_ahead, pos_integer()} | {:delayed_write, non_neg_integer(), non_neg_integer()} | encoding_mode()
@type posix() :: :file.posix()
@type posix_time() :: integer()
@type stat_options() :: [{:time, :local | :universal | :posix}]
@type stream_mode() :: encoding_mode() | :append | :compressed | :trim_bom | {:read_ahead, pos_integer() | false} | {:delayed_write, non_neg_integer(), non_neg_integer()}
Link to this section Functions
Sets the current working directory.
The current working directory is set for the BEAM globally. This can lead to
race conditions if multiple processes are changing the current working
directory concurrently. To run an external command in a given directory
without changing the global current working directory, use the :cd
option
of System.cmd/3
and Port.open/2
.
Returns :ok
if successful, {:error, reason}
otherwise.
@spec cd!(Path.t()) :: :ok
The same as cd/1
, but raises a File.Error
exception if it fails.
@spec cd!(Path.t(), (() -> res)) :: res when res: var
Changes the current directory to the given path
,
executes the given function and then reverts back
to the previous path regardless of whether there is an exception.
The current working directory is temporarily set for the BEAM globally. This
can lead to race conditions if multiple processes are changing the current
working directory concurrently. To run an external command in a given
directory without changing the global current working directory, use the
:cd
option of System.cmd/3
and Port.open/2
.
Raises an error if retrieving or changing the current directory fails.
@spec chgrp(Path.t(), non_neg_integer()) :: :ok | {:error, posix()}
Changes the group given by the group ID gid
for a given file
. Returns :ok
on success, or
{:error, reason}
on failure.
@spec chgrp!(Path.t(), non_neg_integer()) :: :ok
Same as chgrp/2
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
@spec chmod(Path.t(), non_neg_integer()) :: :ok | {:error, posix()}
Changes the mode
for a given file
.
Returns :ok
on success, or {:error, reason}
on failure.
Permissions
File permissions are specified by adding together the following octal modes:
0o400
- read permission: owner0o200
- write permission: owner0o100
- execute permission: owner0o040
- read permission: group0o020
- write permission: group0o010
- execute permission: group0o004
- read permission: other0o002
- write permission: other0o001
- execute permission: other
For example, setting the mode 0o755
gives it
write, read and execute permission to the owner
and both read and execute permission to group
and others.
@spec chmod!(Path.t(), non_neg_integer()) :: :ok
Same as chmod/2
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
@spec chown(Path.t(), non_neg_integer()) :: :ok | {:error, posix()}
Changes the owner given by the user ID uid
for a given file
. Returns :ok
on success,
or {:error, reason}
on failure.
@spec chown!(Path.t(), non_neg_integer()) :: :ok
Same as chown/2
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Closes the file referenced by io_device
. It mostly returns :ok
, except
for some severe errors such as out of memory.
Note that if the option :delayed_write
was used when opening the file,
close/1
might return an old write error and not even try to close the file.
See open/2
for more information.
@spec copy(Path.t() | io_device(), Path.t() | io_device(), pos_integer() | :infinity) :: {:ok, non_neg_integer()} | {:error, posix()}
Copies the contents of source
to destination
.
Both parameters can be a filename or an IO device opened
with open/2
. bytes_count
specifies the number of
bytes to copy, the default being :infinity
.
If file destination
already exists, it is overwritten
by the contents in source
.
Returns {:ok, bytes_copied}
if successful,
{:error, reason}
otherwise.
Compared to the cp/3
, this function is more low-level,
allowing a copy from device to device limited by a number of
bytes. On the other hand, cp/3
performs more extensive
checks on both source and destination and it also preserves
the file mode after copy.
Typical error reasons are the same as in open/2
,
read/1
and write/3
.
@spec copy!(Path.t() | io_device(), Path.t() | io_device(), pos_integer() | :infinity) :: non_neg_integer()
The same as copy/3
but raises a File.CopyError
exception if it fails.
Returns the bytes_copied
otherwise.
cp(source_file, destination_file, callback \\ fn _, _ -> true end)
View SourceCopies the contents of source_file
to destination_file
preserving its modes.
source_file
must be a file or a symbolic link to one. destination_file
must
be a path to a non-existent file. If either is a directory, {:error, :eisdir}
will be returned.
The callback
function is invoked if the destination_file
already exists.
The function receives arguments for source_file
and destination_file
;
it should return true
if the existing file should be overwritten, false
if
otherwise. The default callback returns true
.
The function returns :ok
in case of success. Otherwise, it returns
{:error, reason}
.
If you want to copy contents from an IO device to another device
or do a straight copy from a source to a destination without
preserving modes, check copy/3
instead.
Note: The command cp
in Unix-like systems behaves differently depending on
whether the destination is an existing directory or not. We have chosen to
explicitly disallow copying to a destination which is a directory,
and an error will be returned if tried.
cp!(source_file, destination_file, callback \\ fn _, _ -> true end)
View SourceThe same as cp/3
, but raises a File.CopyError
exception if it fails.
Returns :ok
otherwise.
@spec cp_r(Path.t(), Path.t(), (Path.t(), Path.t() -> boolean())) :: {:ok, [binary()]} | {:error, posix(), binary()}
Copies the contents in source
to destination
recursively, maintaining the
source directory structure and modes.
If source
is a file or a symbolic link to it, destination
must be a path
to an existent file, a symbolic link to one, or a path to a non-existent file.
If source
is a directory, or a symbolic link to it, then destination
must
be an existent directory
or a symbolic link to one, or a path to a non-existent directory.
If the source is a file, it copies source
to
destination
. If the source
is a directory, it copies
the contents inside source into the destination
directory.
If a file already exists in the destination, it invokes callback
.
callback
must be a function that takes two arguments: source
and destination
.
The callback should return true
if the existing file should be overwritten and false
otherwise.
This function may fail while copying files, in such cases, it will leave the destination directory in a dirty state, where file which have already been copied won't be removed.
The function returns {:ok, files_and_directories}
in case of
success, files_and_directories
lists all files and directories copied in no
specific order. It returns {:error, reason, file}
otherwise.
Note: The command cp
in Unix-like systems behaves differently depending on
whether destination
is an existing directory or not. We have chosen to
explicitly disallow this behaviour. If source
is a file
and destination
is a directory, {:error, :eisdir}
will be returned.
Examples
# Copies file "a.txt" to "b.txt"
File.cp_r("a.txt", "b.txt")
# Copies all files in "samples" to "tmp"
File.cp_r("samples", "tmp")
# Same as before, but asks the user how to proceed in case of conflicts
File.cp_r("samples", "tmp", fn source, destination ->
IO.gets("Overwriting #{destination} by #{source}. Type y to confirm. ") == "y\n"
end)
The same as cp_r/3
, but raises a File.CopyError
exception if it fails.
Returns the list of copied files otherwise.
Gets the current working directory.
In rare circumstances, this function can fail on Unix-like systems. It may happen
if read permissions do not exist for the parent directories of the
current directory. For this reason, returns {:ok, cwd}
in case
of success, {:error, reason}
otherwise.
@spec cwd!() :: binary()
The same as cwd/0
, but raises a File.Error
exception if it fails.
Returns true
if the given path is a directory.
This function follows symbolic links, so if a symbolic link points to a
directory, true
is returned.
Options
The supported options are:
:raw
- a single atom to bypass the file server and only check for the file locally
Examples
File.dir?("./test")
#=> true
File.dir?("test")
#=> true
File.dir?("/usr/bin")
#=> true
File.dir?("~/Downloads")
#=> false
"~/Downloads" |> Path.expand() |> File.dir?()
#=> true
Returns true
if the given path exists.
It can be a regular file, directory, socket, symbolic link, named pipe, or device file.
Returns false
for symbolic links pointing to non-existing targets.
Options
The supported options are:
:raw
- a single atom to bypass the file server and only check for the file locally
Examples
File.exists?("test/")
#=> true
File.exists?("missing.txt")
#=> false
File.exists?("/dev/null")
#=> true
Creates a hard link new
to the file existing
.
Returns :ok
if successful, {:error, reason}
otherwise.
If the operating system does not support hard links, returns
{:error, :enotsup}
.
Same as ln/2
but raises a File.LinkError
exception if it fails.
Returns :ok
otherwise.
Creates a symbolic link new
to the file or directory existing
.
Returns :ok
if successful, {:error, reason}
otherwise.
If the operating system does not support symlinks, returns
{:error, :enotsup}
.
Same as ln_s/2
but raises a File.LinkError
exception if it fails.
Returns :ok
otherwise.
Returns the list of files in the given directory.
Returns {:ok, files}
in case of success,
{:error, reason}
otherwise.
The same as ls/1
but raises a File.Error
exception in case of an error.
@spec lstat(Path.t(), stat_options()) :: {:ok, File.Stat.t()} | {:error, posix()}
Returns information about the path
. If the file is a symlink, sets
the type
to :symlink
and returns a File.Stat
struct for the link. For any
other file, returns exactly the same values as stat/2
.
For more details, see :file.read_link_info/2
.
Options
The accepted options are:
:time
- configures how the file timestamps are returned
The values for :time
can be:
:universal
- returns a{date, time}
tuple in UTC (default):local
- returns a{date, time}
tuple using the machine time:posix
- returns the time as integer seconds since epoch
Note: Since file times are stored in POSIX time format on most operating systems,
it is faster to retrieve file information with the time: :posix
option.
@spec lstat!(Path.t(), stat_options()) :: File.Stat.t()
Same as lstat/2
but returns the File.Stat
struct directly,
or raises a File.Error
exception if an error is returned.
Tries to create the directory path
.
Missing parent directories are not created.
Returns :ok
if successful, or {:error, reason}
if an error occurs.
Typical error reasons are:
:eacces
- missing search or write permissions for the parent directories ofpath
:eexist
- there is already a file or directory namedpath
:enoent
- a component ofpath
does not exist:enospc
- there is no space left on the device:enotdir
- a component ofpath
is not a directory; on some platforms,:enoent
is returned instead
@spec mkdir!(Path.t()) :: :ok
Same as mkdir/1
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Tries to create the directory path
.
Missing parent directories are created. Returns :ok
if successful, or
{:error, reason}
if an error occurs.
Typical error reasons are:
:eacces
- missing search or write permissions for the parent directories ofpath
:enospc
- there is no space left on the device:enotdir
- a component ofpath
is not a directory
@spec mkdir_p!(Path.t()) :: :ok
Same as mkdir_p/1
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
@spec open(Path.t(), [mode() | :ram]) :: {:ok, io_device()} | {:error, posix()}
@spec open(Path.t(), (io_device() -> res)) :: {:ok, res} | {:error, posix()} when res: var
Opens the given path
.
In order to write and read files, one must use the functions
in the IO
module. By default, a file is opened in :binary
mode,
which requires the functions IO.binread/2
and IO.binwrite/2
to interact with the file. A developer may pass :utf8
as an
option when opening the file and then all other functions from
IO
are available, since they work directly with Unicode data.
modes_or_function
can either be a list of modes or a function. If it's a
list, it's considered to be a list of modes (that are documented below). If
it's a function, then it's equivalent to calling open(path, [], modes_or_function)
. See the documentation for open/3
for more information
on this function.
The allowed modes:
:binary
- opens the file in binary mode, disabling special handling of Unicode sequences (default mode).:read
- the file, which must exist, is opened for reading.:write
- the file is opened for writing. It is created if it does not exist.If the file does exists, and if write is not combined with read, the file will be truncated.
:append
- the file will be opened for writing, and it will be created if it does not exist. Every write operation to a file opened with append will take place at the end of the file.:exclusive
- the file, when opened for writing, is created if it does not exist. If the file exists, open will return{:error, :eexist}
.:charlist
- when this term is given, read operations on the file will return charlists rather than binaries.:compressed
- makes it possible to read or write gzip compressed files.The compressed option must be combined with either read or write, but not both. Note that the file size obtained with
stat/1
will most probably not match the number of bytes that can be read from a compressed file.:utf8
- this option denotes how data is actually stored in the disk file and makes the file perform automatic translation of characters to and from UTF-8.If data is sent to a file in a format that cannot be converted to the UTF-8 or if data is read by a function that returns data in a format that cannot cope with the character range of the data, an error occurs and the file will be closed.
:delayed_write
,:raw
,:ram
,:read_ahead
,:sync
,{:encoding, ...}
,{:read_ahead, pos_integer}
,{:delayed_write, non_neg_integer, non_neg_integer}
- for more information about these options see:file.open/2
.
This function returns:
{:ok, io_device}
- the file has been opened in the requested mode.io_device
is actually the PID of the process which handles the file. This process monitors the process that originally opened the file (the owner process). If the owner process terminates, the file is closed and the process itself terminates too. If any process to which theio_device
is linked terminates, the file will be closed and the process itself will be terminated.An
io_device
returned from this call can be used as an argument to theIO
module functions.{:error, reason}
- the file could not be opened.
Examples
{:ok, file} = File.open("foo.tar.gz", [:read, :compressed])
IO.read(file, :line)
File.close(file)
@spec open(Path.t(), [mode() | :ram], (io_device() -> res)) :: {:ok, res} | {:error, posix()} when res: var
Similar to open/2
but expects a function as its last argument.
The file is opened, given to the function as an argument and automatically closed after the function returns, regardless if there was an error when executing the function.
Returns {:ok, function_result}
in case of success,
{:error, reason}
otherwise.
This function expects the file to be closed with success,
which is usually the case unless the :delayed_write
option
is given. For this reason, we do not recommend passing
:delayed_write
to this function.
Examples
File.open("file.txt", [:read, :write], fn file ->
IO.read(file, :line)
end)
See open/2
for the list of available modes
.
@spec open!(Path.t(), [mode() | :ram]) :: io_device()
@spec open!(Path.t(), (io_device() -> res)) :: res when res: var
Similar to open/2
but raises a File.Error
exception if the file
could not be opened. Returns the IO device otherwise.
See open/2
for the list of available modes.
Similar to open/3
but raises a File.Error
exception if the file
could not be opened.
If it succeeds opening the file, it returns the function
result on the IO device.
See open/2
for the list of available modes
.
Returns {:ok, binary}
, where binary
is a binary data object that contains the contents
of path
, or {:error, reason}
if an error occurs.
Typical error reasons:
:enoent
- the file does not exist:eacces
- missing permission for reading the file, or for searching one of the parent directories:eisdir
- the named file is a directory:enotdir
- a component of the file name is not a directory; on some platforms,:enoent
is returned instead:enomem
- there is not enough memory for the contents of the file
You can use :file.format_error/1
to get a descriptive string of the error.
Returns a binary with the contents of the given filename,
or raises a File.Error
exception if an error occurs.
Reads the symbolic link at path
.
If path
exists and is a symlink, returns {:ok, target}
, otherwise returns
{:error, reason}
.
For more details, see :file.read_link/1
.
Typical error reasons are:
:einval
- path is not a symbolic link:enoent
- path does not exist:enotsup
- symbolic links are not supported on the current platform
Same as read_link/1
but returns the target directly,
or raises a File.Error
exception if an error is returned.
Returns true
if the path is a regular file.
This function follows symbolic links, so if a symbolic link points to a
regular file, true
is returned.
Options
The supported options are:
:raw
- a single atom to bypass the file server and only check for the file locally
Examples
File.regular?(__ENV__.file)
#=> true
Renames the source
file to destination
file. It can be used to move files
(and directories) between directories. If moving a file, you must fully
specify the destination
filename, it is not sufficient to simply specify
its directory.
Returns :ok
in case of success, {:error, reason}
otherwise.
Note: The command mv
in Unix-like systems behaves differently depending on
whether source
is a file and the destination
is an existing directory.
We have chosen to explicitly disallow this behaviour.
Examples
# Rename file "a.txt" to "b.txt"
File.rename("a.txt", "b.txt")
# Rename directory "samples" to "tmp"
File.rename("samples", "tmp")
The same as rename/2
but raises a File.RenameError
exception if it fails.
Returns :ok
otherwise.
Tries to delete the file path
.
Returns :ok
if successful, or {:error, reason}
if an error occurs.
Note the file is deleted even if in read-only mode.
Typical error reasons are:
:enoent
- the file does not exist:eacces
- missing permission for the file or one of its parents:eperm
- the file is a directory and user is not super-user:enotdir
- a component of the file name is not a directory; on some platforms,:enoent
is returned instead:einval
- filename had an improper type, such as tuple
Examples
File.rm("file.txt")
#=> :ok
File.rm("tmp_dir/")
#=> {:error, :eperm}
@spec rm!(Path.t()) :: :ok
Same as rm/1
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
Removes files and directories recursively at the given path
.
Symlinks are not followed but simply removed, non-existing
files are simply ignored (i.e. doesn't make this function fail).
Returns {:ok, files_and_directories}
with all files and
directories removed in no specific order, {:error, reason, file}
otherwise.
Examples
File.rm_rf("samples")
#=> {:ok, ["samples", "samples/1.txt"]}
File.rm_rf("unknown")
#=> {:ok, []}
Same as rm_rf/1
but raises a File.Error
exception in case of failures,
otherwise the list of files or directories removed.
Tries to delete the dir at path
.
Returns :ok
if successful, or {:error, reason}
if an error occurs.
It returns {:error, :eexist}
if the directory is not empty.
Examples
File.rmdir("tmp_dir")
#=> :ok
File.rmdir("non_empty_dir")
#=> {:error, :eexist}
File.rmdir("file.txt")
#=> {:error, :enotdir}
Same as rmdir/1
, but raises a File.Error
exception in case of failure.
Otherwise :ok
.
@spec stat(Path.t(), stat_options()) :: {:ok, File.Stat.t()} | {:error, posix()}
Returns information about the path
. If it exists, it
returns a {:ok, info}
tuple, where info is a
File.Stat
struct. Returns {:error, reason}
with
the same reasons as read/1
if a failure occurs.
Options
The accepted options are:
:time
- configures how the file timestamps are returned
The values for :time
can be:
:universal
- returns a{date, time}
tuple in UTC (default):local
- returns a{date, time}
tuple using the same time zone as the machine:posix
- returns the time as integer seconds since epoch
Note: Since file times are stored in POSIX time format on most operating systems,
it is faster to retrieve file information with the time: :posix
option.
@spec stat!(Path.t(), stat_options()) :: File.Stat.t()
Same as stat/2
but returns the File.Stat
directly,
or raises a File.Error
exception if an error is returned.
@spec stream!(Path.t(), [stream_mode()], :line | pos_integer()) :: File.Stream.t()
Returns a File.Stream
for the given path
with the given modes
.
The stream implements both Enumerable
and Collectable
protocols,
which means it can be used both for read and write.
The line_or_bytes
argument configures how the file is read when
streaming, by :line
(default) or by a given number of bytes. When
using the :line
option, CRLF line breaks (" "
) are normalized
to LF (" "
).
Operating the stream can fail on open for the same reasons as
File.open!/2
. Note that the file is automatically opened each time streaming
begins. There is no need to pass :read
and :write
modes, as those are
automatically set by Elixir.
Raw files
Since Elixir controls when the streamed file is opened, the underlying
device cannot be shared and as such it is convenient to open the file
in raw mode for performance reasons. Therefore, Elixir will open
streams in :raw
mode with the :read_ahead
option unless an encoding
is specified. This means any data streamed into the file must be
converted to iodata/0
type. If you pass, for example, [encoding: :utf8]
or [encoding: {:utf16, :little}]
in the modes parameter,
the underlying stream will use IO.write/2
and the String.Chars
protocol
to convert the data. See IO.binwrite/2
and IO.write/2
.
One may also consider passing the :delayed_write
option if the stream
is meant to be written to under a tight loop.
Byte order marks
If you pass :trim_bom
in the modes parameter, the stream will
trim UTF-8, UTF-16 and UTF-32 byte order marks when reading from file.
Note that this function does not try to discover the file encoding basing on BOM.
Examples
# 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}
See Stream.run/1
for an example of streaming into a file.
@spec touch(Path.t(), erlang_time() | posix_time()) :: :ok | {:error, posix()}
Updates modification time (mtime) and access time (atime) of the given file.
The file is created if it doesn't exist. Requires datetime in UTC
(as returned by :erlang.universaltime()
) or an integer
representing the POSIX timestamp (as returned by System.os_time(:second)
).
In Unix-like systems, changing the modification time may require
you to be either root
or the owner of the file. Having write
access may not be enough. In those cases, touching the file the
first time (to create it) will succeed, but touching an existing
file with fail with {:error, :eperm}
.
Examples
File.touch("/tmp/a.txt", {{2018, 1, 30}, {13, 59, 59}})
#=> :ok
File.touch("/fakedir/b.txt", {{2018, 1, 30}, {13, 59, 59}})
{:error, :enoent}
File.touch("/tmp/a.txt", 1544519753)
#=> :ok
@spec touch!(Path.t(), erlang_time() | posix_time()) :: :ok
Same as touch/2
but raises a File.Error
exception if it fails.
Returns :ok
otherwise.
The file is created if it doesn't exist. Requires datetime in UTC
(as returned by :erlang.universaltime()
) or an integer
representing the POSIX timestamp (as returned by System.os_time(:second)
).
Examples
File.touch!("/tmp/a.txt", {{2018, 1, 30}, {13, 59, 59}})
#=> :ok
File.touch!("/fakedir/b.txt", {{2018, 1, 30}, {13, 59, 59}})
** (File.Error) could not touch "/fakedir/b.txt": no such file or directory
File.touch!("/tmp/a.txt", 1544519753)
Writes content
to the file path
.
The file is created if it does not exist. If it exists, the previous
contents are overwritten. Returns :ok
if successful, or {:error, reason}
if an error occurs.
content
must be iodata
(a list of bytes or a binary). Setting the
encoding for this function has no effect.
Warning: Every time this function is invoked, a file descriptor is opened
and a new process is spawned to write to the file. For this reason, if you are
doing multiple writes in a loop, opening the file via File.open/2
and using
the functions in IO
to write to the file will yield much better performance
than calling this function multiple times.
Typical error reasons are:
:enoent
- a component of the file name does not exist:enotdir
- a component of the file name is not a directory; on some platforms,:enoent
is returned instead:enospc
- there is no space left on the device:eacces
- missing permission for writing the file or searching one of the parent directories:eisdir
- the named file is a directory
Check File.open/2
for other available options.
Same as write/3
but raises a File.Error
exception if it fails.
Returns :ok
otherwise.
@spec write_stat(Path.t(), File.Stat.t(), stat_options()) :: :ok | {:error, posix()}
Writes the given File.Stat
back to the file system at the given
path. Returns :ok
or {:error, reason}
.
@spec write_stat!(Path.t(), File.Stat.t(), stat_options()) :: :ok
Same as write_stat/3
but raises a File.Error
exception if it fails.
Returns :ok
otherwise.