File View Source

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 OS 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 in source to destination preserving its mode

The same as cp/3, but raises a File.CopyError exception if it fails. Returns :ok otherwise

Copies the contents in source to destination

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

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

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

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

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

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

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

Link to this type

encoding_mode() View Source
encoding_mode() ::
  :utf8
  | {:encoding,
     :latin1
     | :unicode
     | :utf8
     | :utf16
     | :utf32
     | {:utf16, :big | :little}
     | {:utf32, :big | :little}}

Link to this type

erlang_time() View Source
erlang_time() ::
  {{year :: non_neg_integer(), month :: 1..12, day :: 1..31},
   {hour :: 0..23, minute :: 0..59, second :: 0..59}}

Link to this type

mode() View Source
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()

Link to this type

posix_time() View Source
posix_time() :: integer()

Link to this type

stat_options() View Source
stat_options() :: [{:time, :local | :universal | :posix}]

Link to this type

stream_mode() View Source
stream_mode() ::
  encoding_mode()
  | :trim_bom
  | {:read_ahead, pos_integer() | false}
  | {:delayed_write, non_neg_integer(), non_neg_integer()}

Link to this section Functions

Link to this function

cd(path) View Source
cd(Path.t()) :: :ok | {:error, posix()}

Sets the current working directory.

Returns :ok if successful, {:error, reason} otherwise.

The same as cd/1, but raises a File.Error exception if it fails.

Link to this function

cd!(path, function) View Source
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.

Raises an error if retrieving or changing the current directory fails.

Link to this function

chgrp(path, gid) View Source
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.

Link to this function

chgrp!(path, gid) View Source
chgrp!(Path.t(), non_neg_integer()) :: :ok

Same as chgrp/2, but raises a File.Error exception in case of failure. Otherwise :ok.

Link to this function

chmod(path, mode) View Source
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: owner

  • 0o200 - write permission: owner

  • 0o100 - execute permission: owner

  • 0o040 - read permission: group

  • 0o020 - write permission: group

  • 0o010 - execute permission: group

  • 0o004 - read permission: other

  • 0o002 - write permission: other

  • 0o001 - 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.

Link to this function

chmod!(path, mode) View Source
chmod!(Path.t(), non_neg_integer()) :: :ok

Same as chmod/2, but raises a File.Error exception in case of failure. Otherwise :ok.

Link to this function

chown(path, uid) View Source
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.

Link to this function

chown!(path, uid) View Source
chown!(Path.t(), non_neg_integer()) :: :ok

Same as chown/2, but raises a File.Error exception in case of failure. Otherwise :ok.

Link to this function

close(io_device) View Source
close(io_device()) :: :ok | {:error, posix() | :badarg | :terminated}

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.

Link to this function

copy(source, destination, bytes_count \\ :infinity) View Source
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.

Link to this function

copy!(source, destination, bytes_count \\ :infinity) View Source
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.

Link to this function

cp(source, destination, callback \\ fn _, _ -> true end) View Source
cp(Path.t(), Path.t(), (Path.t(), Path.t() -> boolean())) ::
  :ok | {:error, posix()}

Copies the contents in source to destination preserving its mode.

If a file already exists in the destination, it invokes a callback which should return true if the existing file should be overwritten, false otherwise. The callback defaults to return true.

The function returns :ok in case of success, returns {:error, reason} otherwise.

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 systems behaves differently depending if destination is an existing directory or not. We have chosen to explicitly disallow this behaviour. If destination is a directory, an error will be returned.

Link to this function

cp!(source, destination, callback \\ fn _, _ -> true end) View Source
cp!(Path.t(), Path.t(), (Path.t(), Path.t() -> boolean())) :: :ok

The same as cp/3, but raises a File.CopyError exception if it fails. Returns :ok otherwise.

Link to this function

cp_r(source, destination, callback \\ fn _, _ -> true end) View Source
cp_r(Path.t(), Path.t(), (Path.t(), Path.t() -> boolean())) ::
  {:ok, [binary()]} | {:error, posix(), binary()}

Copies the contents in source to destination.

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.

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.

If a directory already exists in the destination where a file is meant to be (or vice versa), this function will fail.

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 systems behaves differently depending if destination is an existing directory or not. We have chosen to explicitly disallow this behaviour.

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)
Link to this function

cp_r!(source, destination, callback \\ fn _, _ -> true end) View Source
cp_r!(Path.t(), Path.t(), (Path.t(), Path.t() -> boolean())) :: [binary()]

The same as cp_r/3, but raises a File.CopyError exception if it fails. Returns the list of copied files otherwise.

Link to this function

cwd() View Source
cwd() :: {:ok, binary()} | {:error, posix()}

Gets the current working directory.

In rare circumstances, this function can fail on Unix. 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.

The same as cwd/0, but raises a File.Error exception if it fails.

Link to this function

dir?(path, opts \\ []) View Source
dir?(Path.t(), [dir_option]) :: boolean() when dir_option: :raw

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
Link to this function

exists?(path, opts \\ []) View Source
exists?(Path.t(), [exists_option]) :: boolean() when exists_option: :raw

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
Link to this function

ln(existing, new) View Source (since 1.5.0)
ln(Path.t(), Path.t()) :: :ok | {:error, posix()}

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}.

Link to this function

ln!(existing, new) View Source (since 1.5.0)
ln!(Path.t(), Path.t()) :: :ok

Same as ln/2 but raises a File.LinkError exception if it fails. Returns :ok otherwise.

Link to this function

ln_s(existing, new) View Source (since 1.5.0)
ln_s(Path.t(), Path.t()) :: :ok | {:error, posix()}

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}.

Link to this function

ln_s!(existing, new) View Source
ln_s!(Path.t(), Path.t()) :: :ok

Same as ln_s/2 but raises a File.LinkError exception if it fails. Returns :ok otherwise.

Link to this function

ls(path \\ ".") View Source
ls(Path.t()) :: {:ok, [binary()]} | {:error, posix()}

Returns the list of files in the given directory.

Returns {:ok, files} in case of success, {:error, reason} otherwise.

Link to this function

ls!(path \\ ".") View Source
ls!(Path.t()) :: [binary()]

The same as ls/1 but raises a File.Error exception in case of an error.

Link to this function

lstat(path, opts \\ []) View Source
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
Link to this function

lstat!(path, opts \\ []) View Source
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.

Link to this function

mkdir(path) View Source
mkdir(Path.t()) :: :ok | {:error, posix()}

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 of path
  • :eexist - there is already a file or directory named path
  • :enoent - a component of path does not exist
  • :enospc - there is no space left on the device
  • :enotdir - a component of path is not a directory; on some platforms, :enoent is returned instead
Link to this function

mkdir!(path) View Source
mkdir!(Path.t()) :: :ok

Same as mkdir/1, but raises a File.Error exception in case of failure. Otherwise :ok.

Link to this function

mkdir_p(path) View Source
mkdir_p(Path.t()) :: :ok | {:error, posix()}

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 of path
  • :enospc - there is no space left on the device
  • :enotdir - a component of path is not a directory
Link to this function

mkdir_p!(path) View Source
mkdir_p!(Path.t()) :: :ok

Same as mkdir_p/1, but raises a File.Error exception in case of failure. Otherwise :ok.

Link to this function

open(path, modes_or_function \\ []) View Source
open(Path.t(), [mode() | :ram]) :: {:ok, io_device()} | {:error, posix()}
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 is linked to the process which originally opened the file. If any process to which the io_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 the IO 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)
Link to this function

open(path, modes, function) View Source
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.

Link to this function

open!(path, modes_or_function \\ []) View Source
open!(Path.t(), [mode() | :ram]) :: io_device()
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.

Link to this function

open!(path, modes, function) View Source
open!(Path.t(), [mode() | :ram], (io_device() -> res)) :: res when res: var

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.

Link to this function

read(path) View Source
read(Path.t()) :: {:ok, binary()} | {:error, posix()}

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.

Link to this function

read_link(path) View Source (since 1.5.0)
read_link(Path.t()) :: {:ok, binary()} | {:error, posix()}

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
Link to this function

read_link!(path) View Source (since 1.5.0)
read_link!(Path.t()) :: binary()

Same as read_link/1 but returns the target directly, or raises a File.Error exception if an error is returned.

Link to this function

regular?(path, opts \\ []) View Source
regular?(Path.t(), [regular_option]) :: boolean() when regular_option: :raw

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
Link to this function

rename(source, destination) View Source
rename(Path.t(), Path.t()) :: :ok | {:error, posix()}

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 systems behaves differently depending if 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")
Link to this function

rm(path) View Source
rm(Path.t()) :: :ok | {:error, posix()}

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}

Same as rm/1, but raises a File.Error exception in case of failure. Otherwise :ok.

Link to this function

rm_rf(path) View Source
rm_rf(Path.t()) :: {:ok, [binary()]} | {:error, posix(), binary()}

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.

Link to this function

rmdir(path) View Source
rmdir(Path.t()) :: :ok | {:error, posix()}

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}
Link to this function

rmdir!(path) View Source
rmdir!(Path.t()) :: :ok | {:error, posix()}

Same as rmdir/1, but raises a File.Error exception in case of failure. Otherwise :ok.

Link to this function

stat(path, opts \\ []) View Source
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

Same as stat/2 but returns the File.Stat directly, or raises a File.Error exception if an error is returned.

Link to this function

stream!(path, modes \\ [], line_or_bytes \\ :line) View Source
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.

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 e.g. [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.

Link to this function

touch(path, time \\ System.os_time(:second)) View Source
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)).

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
Link to this function

touch!(path, time \\ System.os_time(:second)) View Source
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)
Link to this function

write(path, content, modes \\ []) View Source
write(Path.t(), iodata(), [mode()]) :: :ok | {:error, posix()}

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.

Link to this function

write!(path, content, modes \\ []) View Source
write!(Path.t(), iodata(), [mode()]) :: :ok

Same as write/3 but raises a File.Error exception if it fails. Returns :ok otherwise.

Link to this function

write_stat(path, stat, opts \\ []) View Source
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}.

Link to this function

write_stat!(path, stat, opts \\ []) View Source
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.