File interface module.
This module provides an interface to the file system.
Warning!
File operations are only guaranteed to appear atomic when going
through the same file server. A NIF or other OS process may observe
intermediate steps on certain operations on some operating systems,
eg. renaming an existing file on Windows, or
write_file_info/2
on any OS at the time of writing.
Regarding filename encoding, the Erlang VM can operate in
two modes. The current mode can be queried using function
native_name_encoding/0
.
It returns latin1
or utf8
.
In latin1
mode, the Erlang VM does not change the
encoding of filenames. In utf8
mode, filenames can
contain Unicode characters greater than 255 and the VM
converts filenames back and forth to the native filename encoding
(usually UTF-8, but UTF-16 on Windows).
The default mode depends on the operating system. Windows and
MacOS X enforce consistent filename encoding and therefore the
VM uses utf8
mode.
On operating systems with transparent naming (for example, all Unix
systems except MacOS X), default is utf8
if the
terminal supports UTF-8, otherwise latin1
. The default can
be overridden using +fnl
(to force latin1
mode)
or +fnu
(to force utf8
mode) when starting
erl
.
On operating systems with transparent naming, files can be
inconsistently named, for example, some files are encoded in UTF-8 while
others are encoded in ISO Latin-1. The concept of raw filenames is
introduced to handle file systems with inconsistent naming when running in
utf8
mode.
A raw filename is a filename specified as a binary. The Erlang VM does not translate a filename specified as a binary on systems with transparent naming.
When running in utf8
mode, functions
list_dir/1
and
read_link/1
never return raw filenames. To return all filenames including raw filenames,
use functions
list_dir_all/1
and
read_link_all/1
.
See also section Notes About Raw Filenames in the STDLIB User's Guide.
Note!
File operations used to accept filenames containing null characters (integer value zero). This caused the name to be truncated and in some cases arguments to primitive operations to be mixed up. Filenames containing null characters inside the filename are now rejected and will cause primitive file operations fail.
Types
deep_list() = [char() | atom() | deep_list()]
fd()
A file descriptor representing a file opened in
raw
mode.
filename() = string()
See also the documentation of the
name_all()
type.
filename_all() = string() | binary()
See also the documentation of the
name_all()
type.
name() = string() | atom() | deep_list()
If VM is in Unicode filename mode, string()
and char()
are allowed to be > 255. See also the documentation of the
name_all()
type.
name_all() =
string() | atom() | deep_list() | (RawFilename :: binary())
If VM is in Unicode filename mode, characters
are allowed to be > 255.
is a filename not subject to
Unicode translation,
meaning that it can contain characters not conforming to
the Unicode encoding expected from the file system
(that is, non-UTF-8 characters although the VM is started
in Unicode filename mode). Null characters (integer value zero)
are not allowed in filenames (not even at the end).
posix() =
eacces | eagain | ebadf | ebadmsg | ebusy | edeadlk |
edeadlock | edquot | eexist | efault | efbig | eftype |
eintr | einval | eio | eisdir | eloop | emfile | emlink |
emultihop | enametoolong | enfile | enobufs | enodev |
enolck | enolink | enoent | enomem | enospc | enosr | enostr |
enosys | enotblk | enotdir | enotsup | enxio | eopnotsupp |
eoverflow | eperm | epipe | erange | erofs | espipe | esrch |
estale | etxtbsy | exdev
An atom that is named from the POSIX error codes used in Unix, and in the runtime libraries of most C compilers.
date_time() = calendar:datetime()
Must denote a valid date and time.
file_info() =
#file_info{size = integer() >= 0 | undefined,
type =
device | directory | other | regular |
symlink | undefined,
access =
read | write | read_write | none | undefined,
atime =
file:date_time() |
integer() >= 0 |
undefined,
mtime =
file:date_time() |
integer() >= 0 |
undefined,
ctime =
file:date_time() |
integer() >= 0 |
undefined,
mode = integer() >= 0 | undefined,
links = integer() >= 0 | undefined,
major_device = integer() >= 0 | undefined,
minor_device = integer() >= 0 | undefined,
inode = integer() >= 0 | undefined,
uid = integer() >= 0 | undefined,
gid = integer() >= 0 | undefined}
location() =
integer() |
{bof, Offset :: integer()} |
{cur, Offset :: integer()} |
{eof, Offset :: integer()} |
bof | cur | eof
mode() =
read | write | append | exclusive | raw | binary |
{delayed_write,
Size :: integer() >= 0,
Delay :: integer() >= 0} |
delayed_write |
{read_ahead, Size :: integer() >= 1} |
read_ahead | compressed |
{encoding, unicode:encoding()} |
sync
file_info_option() =
{time, local} | {time, universal} | {time, posix} | raw
Functions
advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason}
IoDevice = io_device()
Offset = Length = integer()
Advise = posix_file_advise()
Reason = posix() | badarg
posix_file_advise() =
normal | sequential | random | no_reuse | will_need |
dont_need
advise/4
can be used to announce an intention to access file
data in a specific pattern in the future, thus allowing the
operating system to perform appropriate optimizations.
On some platforms, this function might have no effect.
allocate(File, Offset, Length) -> ok | {error, posix()}
File = io_device()
Offset = Length = integer() >= 0
allocate/3
can be used to preallocate space for a file.
This function only succeeds in platforms that provide this feature. When it succeeds, space is preallocated for the file but the file size might not be updated. This behaviour depends on the preallocation implementation. To guarantee that the file size is updated, truncate the file to the new size.
change_group(Filename, Gid) -> ok | {error, Reason}
Filename = name_all()
Gid = integer()
Reason = posix() | badarg
Changes group of a file. See
write_file_info/2
.
change_mode(Filename, Mode) -> ok | {error, Reason}
Filename = name_all()
Mode = integer()
Reason = posix() | badarg
Changes permissions of a file. See
write_file_info/2
.
change_owner(Filename, Uid) -> ok | {error, Reason}
Filename = name_all()
Uid = integer()
Reason = posix() | badarg
Changes owner of a file. See
write_file_info/2
.
change_owner(Filename, Uid, Gid) -> ok | {error, Reason}
Filename = name_all()
Uid = Gid = integer()
Reason = posix() | badarg
Changes owner and group of a file. See
write_file_info/2
.
change_time(Filename, Mtime) -> ok | {error, Reason}
Filename = name_all()
Mtime = date_time()
Reason = posix() | badarg
Changes the modification and access times of a file. See
write_file_info/2
.
change_time(Filename, Atime, Mtime) -> ok | {error, Reason}
Filename = name_all()
Atime = Mtime = date_time()
Reason = posix() | badarg
Changes the modification and last access times of a file. See
write_file_info/2
.
close(IoDevice) -> ok | {error, Reason}
IoDevice = io_device()
Reason = posix() | badarg | terminated
Closes the file referenced by
. It mostly
returns ok
, except for some severe errors such as out
of memory.
Notice that if option delayed_write
was
used when opening the file, close/1
can return an
old write error and not even try to close the file. See
open/2
.
consult(Filename) -> {ok, Terms} | {error, Reason}
Filename = name_all()
Terms = [term()]
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}
Reads Erlang terms, separated by '.', from
. Returns one of the following:
{ok, Terms }
The file was successfully read.
{error, atom()}
An error occurred when opening the file or reading it.
For a list of typical error codes, see
open/2
.
{error, {Line , Mod ,
Term }}
An error occurred when interpreting the Erlang terms in
the file. To convert the three-element tuple to an English
description of the error, use
format_error/1
.
Example:
f.txt: {person, "kalle", 25}. {person, "pelle", 30}.
1> file:consult("f.txt").
{ok,[{person,"kalle",25},{person,"pelle",30}]}
The encoding of
can be set
by a comment, as described in
epp(3)
.
copy(Source, Destination) -> {ok, BytesCopied} | {error, Reason}
Source = Destination = io_device() | Filename | {Filename, Modes}
Filename = name_all()
Modes = [mode()]
BytesCopied = integer() >= 0
Reason = posix() | badarg | terminated
copy(Source, Destination, ByteCount) ->
{ok, BytesCopied} | {error, Reason}
Source = Destination = io_device() | Filename | {Filename, Modes}
Filename = name_all()
Modes = [mode()]
ByteCount = integer() >= 0 | infinity
BytesCopied = integer() >= 0
Reason = posix() | badarg | terminated
Copies
bytes from
to
.
and
refer
to either filenames or IO devices from, for example, open/2
.
defaults to infinity
, denoting an
infinite number of bytes.
Argument
is a list of possible modes,
see open/2
, and defaults to
[]
.
If both
and
refer to
filenames, the files are opened with [read, binary]
and [write, binary]
prepended to their mode lists,
respectively, to optimize the copy.
If
refers to a filename, it is opened with
read
mode prepended to the mode list before the copy,
and closed when done.
If
refers to a filename, it is opened
with write
mode prepended to the mode list before
the copy, and closed when done.
Returns {ok,
, where
is
the number of bytes that was copied, which can be
less than
if end of file was
encountered on the source. If the operation fails,
{error,
is returned.
Typical error reasons: as for
open/2
if a file
had to be opened, and as for
read/2
and
write/2
.
datasync(IoDevice) -> ok | {error, Reason}
IoDevice = io_device()
Reason = posix() | badarg | terminated
Ensures that any buffers kept by the operating system
(not by the Erlang runtime system) are written to disk. In
many ways it resembles fsync
but it does not update
some of the metadata of the file, such as the access time. On
some platforms this function has no effect.
Applications that access databases or log files often write
a tiny data fragment (for example, one line in a log file) and then
call fsync()
immediately to ensure that the written
data is physically stored on the hard disk. Unfortunately, fsync()
always initiates two write operations: one for the newly
written data and another one to update the modification
time stored in the inode
. If the modification time is not a part
of the transaction concept, fdatasync()
can be used to avoid
unnecessary inode
disk write operations.
Available only in some POSIX systems, this call results in a
call to fsync()
, or has no effect in systems not providing
the fdatasync()
syscall.
del_dir(Dir) -> ok | {error, Reason}
Dir = name_all()
Reason = posix() | badarg
Tries to delete directory
.
The directory must
be empty before it can be deleted. Returns ok
if
successful.
Typical error reasons:
eacces
Missing search or write permissions for the parent
directories of
.
eexist
The directory is not empty.
enoent
The directory does not exist.
enotdir
A component of
is not a directory.
On some platforms, enoent
is returned instead.
einval
Attempt to delete the current directory. On some
platforms, eacces
is returned instead.
delete(Filename) -> ok | {error, Reason}
Filename = name_all()
Reason = posix() | badarg
Tries to delete file
.
Returns ok
if successful.
Typical error reasons:
enoent
The file does not exist.
eacces
Missing permission for the file or one of its parents.
eperm
The file is a directory and the user is not superuser.
enotdir
A component of the filename is not a directory. On some
platforms, enoent
is returned instead.
einval
has an improper type, such as tuple.
Warning!
In a future release, a bad type for argument
will probably generate
an exception.
eval(Filename) -> ok | {error, Reason}
Filename = name_all()
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}
Reads and evaluates Erlang expressions, separated by '.' (or
',', a sequence of expressions is also an expression) from
. The result of the evaluation
is not returned; any expression sequence in the file must be there
for its side effect. Returns one of the following:
ok
The file was read and evaluated.
{error, atom()}
An error occurred when opening the file or reading it.
For a list of typical error codes, see
open/2
.
{error, {Line , Mod ,
Term }}
An error occurred when interpreting the Erlang
expressions in the file. To convert the three-element tuple
to an English description of the error, use
format_error/1
.
The encoding of
can be set
by a comment, as described in
epp(3)
.
eval(Filename, Bindings) -> ok | {error, Reason}
Filename = name_all()
Bindings = erl_eval:binding_struct()
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}
The same as eval/1
, but the variable bindings
are used in the evaluation. For information
about the variable bindings, see
erl_eval(3)
.
format_error(Reason) -> Chars
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}Chars = string()
Given the error reason returned by any function in this module, returns a descriptive string of the error in English.
get_cwd() -> {ok, Dir} | {error, Reason}
Dir = filename()
Reason = posix()
Returns {ok,
, where
is the current
working directory of the file server.
Note!
In rare circumstances, this function can fail on Unix. It can occur if read permission does not exist for the parent directories of the current directory.
A typical error reason:
eacces
Missing read permission for one of the parents of the current directory.
get_cwd(Drive) -> {ok, Dir} | {error, Reason}
Drive = string()
Dir = filename()
Reason = posix() | badarg
Returns {ok,
or
{error,
, where
is the current working directory of the specified drive.
is to be of the form
"Letter
:
", for example, "c:".
Returns {error, enotsup}
on platforms
that have no concept of current drive (Unix, for example).
Typical error reasons:
enotsup
The operating system has no concept of drives.
eacces
The drive does not exist.
einval
The format of
is invalid.
list_dir(Dir) -> {ok, Filenames} | {error, Reason}
Dir = name_all()
Filenames = [filename()]
Reason =
posix() |
badarg |
{no_translation, Filename :: unicode:latin1_binary()}
Lists all files in a directory, except files
with raw filenames. Returns
{ok,
if successful,
otherwise {error,
.
is a list of
the names of all the files in the directory. The names are
not sorted.
Typical error reasons:
eacces
Missing search or write permissions for
or one of its parent directories.
enoent
The directory does not exist.
{no_translation, Filename }
is a binary()
with
characters coded in ISO Latin-1 and the VM was started
with parameter +fnue
.
list_dir_all(Dir) -> {ok, Filenames} | {error, Reason}
Dir = name_all()
Filenames = [filename_all()]
Reason = posix() | badarg
Lists all the files in a directory,
including files with raw filenames.
Returns {ok,
if successful,
otherwise {error,
.
is a list of
the names of all the files in the directory. The names are
not sorted.
Typical error reasons:
eacces
Missing search or write permissions for
or one of its parent directories.
enoent
The directory does not exist.
make_dir(Dir) -> ok | {error, Reason}
Dir = name_all()
Reason = posix() | badarg
Tries to create directory
. Missing parent
directories are not created. Returns ok
if
successful.
Typical error reasons:
eacces
Missing search or write permissions for the parent
directories of
.
eexist
A file or directory named
exists already.
enoent
A component of
does not exist.
enospc
No space is left on the device.
enotdir
A component of
is not a directory.
On some platforms, enoent
is returned instead.
make_link(Existing, New) -> ok | {error, Reason}
Existing = New = name_all()
Reason = posix() | badarg
Makes a hard link from
to
on
platforms supporting links (Unix and Windows). This function returns
ok
if the link was successfully created, otherwise
{error,
. On platforms not supporting
links, {error,enotsup}
is returned.
Typical error reasons:
eacces
Missing read or write permissions for the parent
directories of
or
.
eexist
already exists.
enotsup
Hard links are not supported on this platform.
make_symlink(Existing, New) -> ok | {error, Reason}
Existing = New = name_all()
Reason = posix() | badarg
Creates a symbolic link
to
the file or directory
on platforms
supporting symbolic links (most Unix systems and Windows, beginning with
Vista).
does not need to exist.
Returns ok
if the link is
successfully created, otherwise {error,
.
On platforms not supporting symbolic links, {error, enotsup}
is returned.
Typical error reasons:
eacces
Missing read or write permissions for the parent directories
of
or
.
eexist
already exists.
enotsup
Symbolic links are not supported on this platform.
eperm
User does not have privileges to create symbolic links
(SeCreateSymbolicLinkPrivilege
on Windows).
native_name_encoding() -> latin1 | utf8
Returns
the filename encoding mode. If it is latin1
, the
system translates no filenames. If it is
utf8
, filenames are converted back and forth to
the native filename encoding (usually UTF-8, but UTF-16 on
Windows).
open(File, Modes) -> {ok, IoDevice} | {error, Reason}
File = Filename | iodata()
Filename = name_all()
Modes = [mode() | ram]
IoDevice = io_device()
Reason = posix() | badarg | system_limit
Opens file
in the mode determined
by
, which can contain one or more of the
following options:
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 exists and write
is not
combined with read
, the file is truncated.
append
The file is opened for writing. It is created if it does
not exist. Every write operation to a file opened with
append
takes place at the end of the file.
exclusive
The file is opened for writing. It is created if it does
not exist. If the file exists, {error, eexist}
is returned.
Warning!
This option does not guarantee exclusiveness on
file systems not supporting O_EXCL
properly,
such as NFS. Do not depend on this option unless you
know that the file system supports it (in general, local
file systems are safe).
raw
Allows faster access to a file, as no Erlang process is needed to handle the file. However, a file opened in this way has the following limitations:
The functions in the
io
module cannot be used, as they can only talk to an Erlang process. Instead, use functionsread/2
,read_line/1
, andwrite/2
.Especially if
read_line/1
is to be used on araw
file, it is recommended to combine this option with option{read_ahead, Size}
as line-oriented I/O is inefficient without buffering.Only the Erlang process that opened the file can use it.
A remote Erlang file server cannot be used. The computer on which the Erlang node is running must have access to the file system (directly or through NFS).
binary
Read operations on the file return binaries rather than lists.
{delayed_write, Size, Delay}
Data in subsequent
write/2
calls is buffered until at least
Size
bytes are buffered, or until the oldest buffered
data is Delay
milliseconds old. Then all buffered
data is written in one operating system call.
The buffered data is also flushed before some other file
operation than write/2
is executed.
The purpose of this option is to increase performance
by reducing the number of operating system calls. Thus, the
write/2
calls must be for sizes significantly
less than Size
, and not interspersed by too many
other file operations.
When this option is used, the result of write/2
calls can prematurely be reported as successful, and if
a write error occurs, the error is reported as the result
of the next file operation, which is not executed.
For example, when delayed_write
is used, after a
number of write/2
calls, close/1
can
return {error, enospc}
, as there is not enough
space on the disc for previously written data.
close/1
must probably be called again, as the
file is still open.
delayed_write
The same as {delayed_write, Size, Delay}
with
reasonable default values for Size
and
Delay
(roughly some 64 KB, 2 seconds).
{read_ahead, Size}
Activates read data buffering. If
read/2
calls are for significantly less than
Size
bytes, read operations to the operating
system are still performed for blocks of Size
bytes. The extra data is buffered and returned in
subsequent read/2
calls, giving a performance gain
as the number of operating system calls is reduced.
The read_ahead
buffer is also highly used
by function read_line/1
in raw
mode,
therefore this option is recommended
(for performance reasons)
when accessing raw files using that function.
If read/2
calls are for sizes not significantly
less than, or even greater than Size
bytes, no
performance gain can be expected.
read_ahead
The same as {read_ahead, Size}
with a reasonable
default value for Size
(roughly some 64 KB).
compressed
Makes it possible to read or write gzip compressed
files. Option compressed
must be combined
with read
or write
, but not both.
Notice that the file size obtained with
read_file_info/1
does probably not match the number of bytes that can be
read from a compressed file.
{encoding, Encoding}
Makes the file perform automatic translation of characters to
and from a specific (Unicode) encoding. Notice that the data supplied
to
write/2
or returned by
read/2
still is byte-oriented; this option
denotes only how data is stored in the disk file.
Depending on the encoding, different methods of reading and writing
data is preferred. The default encoding of latin1
implies using
this module (file
) for reading and writing data as the interfaces
provided here work with byte-oriented data. Using other (Unicode)
encodings makes the
io(3)
functions
get_chars
, get_line
, and put_chars
more suitable,
as they can work with the full Unicode range.
If data is sent to an io_device()
in a format that cannot be
converted to the specified encoding, 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 is closed.
Allowed values for Encoding
:
latin1
The default encoding. Bytes supplied to the file, that is,
write/2
are written "as is" on the file. Likewise, bytes read from the file,
that is,
read/2
are
returned "as is". If module
io(3)
is used for
writing, the file can only cope with Unicode characters up to code point
255 (the ISO Latin-1 range).
unicode or utf8
Characters are translated to and from UTF-8 encoding before they are
written to or read from the file. A file opened in this way can be
readable using function
read/2
,
as long as no data stored on
the file lies beyond the ISO Latin-1 range (0..255), but failure occurs
if the data contains Unicode code points beyond that range. The file is
best read with the functions in the Unicode aware module
io(3)
.
Bytes written to the file by any means are translated to UTF-8 encoding before being stored on the disk file.
utf16 or {utf16,big}
Works like unicode
, but translation is done to and from big
endian UTF-16 instead of UTF-8.
{utf16,little}
Works like unicode
, but translation is done to and from little
endian UTF-16 instead of UTF-8.
utf32 or {utf32,big}
Works like unicode
, but translation is done to and from big
endian UTF-32 instead of UTF-8.
{utf32,little}
Works like unicode
, but translation is done to and from little
endian UTF-32 instead of UTF-8.
The Encoding can be changed for a file "on the fly" by using function
io:setopts/2
.
So a file can be analyzed in latin1 encoding for, for example, a BOM,
positioned beyond the BOM and then be set for the right encoding before
further reading. For functions identifying BOMs, see module
unicode(3)
.
This option is not allowed on raw
files.
ram
File
must be iodata()
. Returns an fd()
, which lets
module file
operate on the data in-memory as if it is a file.
sync
On platforms supporting it, enables the POSIX O_SYNC
synchronous
I/O flag or its platform-dependent equivalent (for example,
FILE_FLAG_WRITE_THROUGH
on Windows) so that writes to the file
block until the data is physically written to disk. However, be aware
that the exact semantics of this flag differ from platform to
platform. For example, none of Linux or Windows guarantees that all file
metadata are also written before the call returns. For precise semantics,
check the details of your platform documentation. On platforms with no
support for POSIX O_SYNC
or equivalent, use of the sync
flag causes open
to return {error, enotsup}
.
Returns:
{ok, IoDevice }
The file is opened in the requested mode.
is a reference to the file.
{error, Reason }
The file cannot be opened.
is really the pid of the process that
handles the file. This process is linked to the process
that originally opened the file. If any process to which
the
is linked terminates, the file is
closed and the process itself is terminated.
An
returned from this call can be used
as an argument to the I/O functions (see
io(3)
).
Note!
In previous versions of file
, modes were specified
as one of the atoms read
, write
, or
read_write
instead of a list. This is still allowed
for reasons of backwards compatibility, but is not to be
used for new code. Also note that read_write
is not
allowed in a mode list.
Typical error reasons:
enoent
The file does not exist.
eacces
Missing permission for reading the file or searching one of the parent directories.
eisdir
The named file is a directory.
enotdir
A component of the filename is not a directory. On some
platforms, enoent
is returned instead.
enospc
There is no space left on the device (if write
access was specified).
path_consult(Path, Filename) ->
{ok, Terms, FullName} | {error, Reason}
Path = [Dir]
Dir = Filename = name_all()
Terms = [term()]
FullName = filename_all()
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}
Searches the path
(a list of directory
names) until the file
is found.
If
is an absolute filename,
is ignored.
Then reads Erlang terms, separated by '.', from the file.
Returns one of the following:
{ok, Terms , FullName }
The file is successfully read.
is
the full name of the file.
{error, enoent}
The file cannot be found in any of the directories in
.
{error, atom()}
An error occurred when opening the file or reading it.
For a list of typical error codes, see
open/2
.
{error, {Line , Mod ,
Term }}
An error occurred when interpreting the Erlang terms in
the file. Use
format_error/1
to convert the three-element tuple to an English description of
the error.
The encoding of
can be set
by a comment as described in
epp(3)
.
path_eval(Path, Filename) -> {ok, FullName} | {error, Reason}
Path = [Dir :: name_all()]
Filename = name_all()
FullName = filename_all()
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}
Searches the path
(a list of directory
names) until the file
is found.
If
is an absolute filename,
is ignored. Then reads
and evaluates Erlang expressions, separated by '.' (or ',', a
sequence of expressions is also an expression), from the file.
The result of evaluation is not returned; any
expression sequence in the file must be there for its side
effect.
Returns one of the following:
{ok, FullName }
The file is read and evaluated.
is
the full name of the file.
{error, enoent}
The file cannot be found in any of the directories in
.
{error, atom()}
An error occurred when opening the file or reading it.
For a list of typical error codes, see
open/2
.
{error, {Line , Mod ,
Term }}
An error occurred when interpreting the Erlang
expressions in the file. Use
format_error/1
to convert the three-element tuple to an English description
of the error.
The encoding of
can be set
by a comment as described in
epp(3)
.
path_open(Path, Filename, Modes) ->
{ok, IoDevice, FullName} | {error, Reason}
Path = [Dir :: name_all()]
Filename = name_all()
Modes = [mode()]
IoDevice = io_device()
FullName = filename_all()
Reason = posix() | badarg | system_limit
Searches the path
(a list of directory
names) until the file
is found.
If
is an absolute filename,
is ignored.
Then opens the file in the mode determined by
.
Returns one of the following:
{ok, IoDevice , FullName }
The file is opened in the requested mode.
is a reference to the file and
is the full name of the file.
{error, enoent}
The file cannot be found in any of the directories in
.
{error, atom()}
The file cannot be opened.
path_script(Path, Filename) ->
{ok, Value, FullName} | {error, Reason}
Path = [Dir :: name_all()]
Filename = name_all()
Value = term()
FullName = filename_all()
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}
Searches the path
(a list of directory
names) until the file
is found.
If
is an absolute filename,
is ignored. Then reads
and evaluates Erlang expressions, separated by '.' (or ',', a
sequence of expressions is also an expression), from the file.
Returns one of the following:
{ok, Value , FullName }
The file is read and evaluated.
is
the full name of the file and
the value of
the last expression.
{error, enoent}
The file cannot be found in any of the directories in
.
{error, atom()}
An error occurred when opening the file or reading it.
For a list of typical error codes, see
open/2
.
{error, {Line , Mod ,
Term }}
An error occurred when interpreting the Erlang
expressions in the file. Use
format_error/1
to convert the three-element tuple to an English description
of the error.
The encoding of
can be set
by a comment as described in
epp(3)
.
path_script(Path, Filename, Bindings) ->
{ok, Value, FullName} | {error, Reason}
Path = [Dir :: name_all()]
Filename = name_all()
Bindings = erl_eval:binding_struct()
Value = term()
FullName = filename_all()
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}
The same as path_script/2
but the variable bindings
are used in the evaluation. See
erl_eval(3)
about
variable bindings.
pid2name(Pid) -> {ok, Filename} | undefined
Filename = filename_all()
Pid = pid()
If
is an I/O device, that is, a pid returned from
open/2
, this function returns the filename, or rather:
{ok, Filename }
If the file server of this node is not a slave, the file was
opened by the file server of this node (this implies that
must be a local pid) and the file is not
closed.
is the filename in flat string
format.
undefined
In all other cases.
Warning!
This function is intended for debugging only.
position(IoDevice, Location) ->
{ok, NewPosition} | {error, Reason}
IoDevice = io_device()
Location = location()
NewPosition = integer()
Reason = posix() | badarg | terminated
Sets the position of the file referenced by
to
. Returns {ok,
(as absolute offset) if successful, otherwise
{error,
.
is
one of the following:
Offset
The same as {bof, Offset}
.
{bof, Offset}
Absolute offset.
{cur, Offset}
Offset from the current position.
{eof, Offset}
Offset from the end of file.
bof | cur | eof
The same as above with Offset
0.
Notice that offsets are counted in bytes, not in characters. If the file
is opened using some other encoding
than latin1
, one byte
does not correspond to one character. Positioning in such a file can only
be done to known character boundaries. That is, to a position earlier retrieved
by getting a current position, to the beginning/end of the file or to some
other position known to be on a correct character boundary by some
other means (typically beyond a byte order mark in the file, which has a
known byte-size).
A typical error reason is:
einval
Either
is illegal, or it is
evaluated to a
negative offset in the file. Notice that if the resulting
position is a negative value, the result is an error, and
after the call the file position is undefined.
pread(IoDevice, LocNums) -> {ok, DataL} | eof | {error, Reason}
IoDevice = io_device()
LocNums =
[{Location :: location(), Number :: integer() >= 0}]DataL = [Data]
Data = string() | binary() | eof
Reason = posix() | badarg | terminated
Performs a sequence of pread/3
in one operation,
which is more efficient than calling them one at a time.
Returns {ok, [
or
{error,
,
where each
, the result of the corresponding
pread
, is either a list or a binary depending on
the mode of the file, or eof
if the requested position
is beyond end of file.
As the position is specified as a byte-offset, take special caution
when working with files where encoding
is set to something else
than latin1
, as not every byte position is a valid character
boundary on such a file.
pread(IoDevice, Location, Number) ->
{ok, Data} | eof | {error, Reason}
IoDevice = io_device()
Location = location()
Number = integer() >= 0
Data = string() | binary()
Reason = posix() | badarg | terminated
Combines position/2
and read/2
in one
operation, which is more efficient than calling them one at a
time. If
is opened in raw
mode,
some restrictions apply:
is only allowed to be an integer.Location - The current position of the file is undefined after the operation.
As the position is specified as a byte-offset, take special caution
when working with files where encoding
is set to something else
than latin1
, as not every byte position is a valid character
boundary on such a file.
pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}}
IoDevice = io_device()
LocBytes = [{Location :: location(), Bytes :: iodata()}]
N = integer() >= 0
Reason = posix() | badarg | terminated
Performs a sequence of pwrite/3
in one operation,
which is more efficient than calling them one at a time.
Returns ok
or {error, {
, where
is the number of successful writes done
before the failure.
When positioning in a file with other encoding
than latin1
,
caution must be taken to set the position on a correct character boundary.
For details, see position/2
.
pwrite(IoDevice, Location, Bytes) -> ok | {error, Reason}
IoDevice = io_device()
Location = location()
Bytes = iodata()
Reason = posix() | badarg | terminated
Combines position/2
and write/2
in one
operation, which is more efficient than calling them one at a
time. If
has been opened in raw
mode,
some restrictions apply:
is only allowed to be an integer.Location - The current position of the file is undefined after the operation.
When positioning in a file with other encoding
than latin1
,
caution must be taken to set the position on a correct character boundary.
For details, see position/2
.
read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason}
IoDevice = io_device() | atom()
Number = integer() >= 0
Data = string() | binary()
Reason =
posix() |
badarg | terminated |
{no_translation, unicode, latin1}
Reads
bytes/characters from the file
referenced by
. The functions
read/2
,
pread/3
, and
read_line/1
are the only ways to read from a file opened in raw
mode
(although they work for normally opened files, too).
For files where encoding
is set to something else than latin1
,
one character can be represented by more than one byte on the file.
The parameter Number
always denotes the number of characters
read from the file, while the position in the file can be moved much more than
this number when reading a Unicode file.
Also, if encoding
is set to something else than latin1
,
the read/3
call fails if the data contains characters larger than 255,
which is why module io(3)
is to be preferred when reading such a file.
The function returns:
{ok, Data }
If the file was opened in binary mode, the read bytes are returned in a binary, otherwise in a list. The list or binary is shorter than the number of bytes requested if end of file was reached.
eof
Returned if
and end of file was
reached before anything at all could be read.
{error, Reason }
An error occurred.
Typical error reasons:
ebadf
The file is not opened for reading.
{no_translation, unicode, latin1}
The file is opened with another encoding
than latin1
and
the data in the file cannot be translated to the byte-oriented data that
this function returns.
read_file(Filename) -> {ok, Binary} | {error, Reason}
Filename = name_all()
Binary = binary()
Reason = posix() | badarg | terminated | system_limit
Returns {ok,
, where
is a binary
data object that contains the contents of
, or
{error,
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 filename is not a directory. On some
platforms, enoent
is returned instead.
enomem
There is not enough memory for the contents of the file.
read_file_info(Filename) -> {ok, FileInfo} | {error, Reason}
Filename = name_all()
FileInfo = file_info()
Reason = posix() | badarg
read_file_info(Filename, Opts) -> {ok, FileInfo} | {error, Reason}
Filename = name_all()
Opts = [file_info_option()]
FileInfo = file_info()
Reason = posix() | badarg
Retrieves information about a file. Returns
{ok,
if successful, otherwise
{error,
.
is a record
file_info
, defined in the Kernel include file
file.hrl
. Include the following directive in the module
from which the function is called:
-include_lib("kernel/include/file.hrl").
The time type returned in atime
, mtime
, and ctime
is dependent on the time type set in Opts :: {time, Type}
as
follows:
local
Returns local time.
universal
Returns universal time.
posix
Returns seconds since or before Unix time epoch, which is 1970-01-01 00:00 UTC.
Default is {time, local}
.
If the option raw
is set, the file server is not called and
only information about local files is returned. Note that this will
break this module's atomicity guarantees as it can race with a
concurrent call to
write_file_info/1,2
Note!
As file times are stored in POSIX time on most OS, it is faster to
query file information with option posix
.
The record file_info
contains the following fields:
size = integer() >= 0
Size of file in bytes.
type = device | directory | other | regular | symlink
The type of the file.
access = read | write | read_write | none
The current system access to the file.
atime =
date_time()
|
integer() >= 0
The last time the file was read.
mtime =
date_time()
|
integer() >= 0
The last time the file was written.
ctime =
date_time()
|
integer() >=0
The interpretation of this time field depends on
the operating system. On Unix, it is the last time
the file or the inode
was changed. In Windows, it is
the create time.
mode = integer() >= 0
The file permissions as the sum of the following bit values:
8#00400
read permission: owner
8#00200
write permission: owner
8#00100
execute permission: owner
8#00040
read permission: group
8#00020
write permission: group
8#00010
execute permission: group
8#00004
read permission: other
8#00002
write permission: other
8#00001
execute permission: other
16#800
set user id on execution
16#400
set group id on execution
On Unix platforms, other bits than those listed above may be set.
links = integer() >= 0
Number of links to the file (this is always 1 for file systems that have no concept of links).
major_device = integer() >= 0
Identifies the file system where the file is located. In Windows, the number indicates a drive as follows: 0 means A:, 1 means B:, and so on.
minor_device = integer() >= 0
Only valid for character devices on Unix. In all other cases, this field is zero.
inode = integer() >= 0
Gives the inode
number. On non-Unix file systems,
this field is zero.
uid = integer() >= 0
Indicates the owner of the file. On non-Unix file systems, this field is zero.
gid = integer() >= 0
Gives the group that the owner of the file belongs to. On non-Unix file systems, this field is zero.
Typical error reasons:
eacces
Missing search permission for one of the parent directories of the file.
enoent
The file does not exist.
enotdir
A component of the filename is not a directory. On some
platforms, enoent
is returned instead.
read_line(IoDevice) -> {ok, Data} | eof | {error, Reason}
IoDevice = io_device() | atom()
Data = string() | binary()
Reason =
posix() |
badarg | terminated |
{no_translation, unicode, latin1}
Reads a line of bytes/characters from the file referenced by
. Lines are defined to be delimited by the
linefeed (LF, \n
) character, but any carriage return (CR, \r
)
followed by a newline is also treated as a single LF character (the carriage
return is silently ignored). The line is returned including the LF,
but excluding any CR immediately followed by an LF. This behaviour is
consistent with the behaviour of
io:get_line/2
.
If end of file is reached without any LF ending the last line, a line with no
trailing LF is returned.
The function can be used on files opened in raw
mode. However, it is
inefficient to use it on raw
files if the file is not opened with
option {read_ahead, Size}
specified. Thus, combining raw
and
{read_ahead, Size}
is highly recommended when opening a text file for
raw line-oriented reading.
If encoding
is set to something else than latin1
, the
read_line/1
call fails if the data contains characters larger than 255,
why module io(3)
is to be
preferred when reading such a file.
The function returns:
{ok, Data }
One line from the file is returned, including the trailing LF, but with CRLF sequences replaced by a single LF (see above).
If the file is opened in binary mode, the read bytes are returned in a binary, otherwise in a list.
eof
Returned if end of file was reached before anything at all could be read.
{error, Reason }
An error occurred.
Typical error reasons:
ebadf
The file is not opened for reading.
{no_translation, unicode, latin1}
The file is opened with another encoding
than latin1
and
the data on the file cannot be translated to the byte-oriented data that
this function returns.
read_link(Name) -> {ok, Filename} | {error, Reason}
Name = name_all()
Filename = filename()
Reason = posix() | badarg
Returns
{ok,
if
refers to a symbolic link that is
not a raw filename, or {error,
otherwise.
On platforms that do not support symbolic links, the return
value is {error,enotsup}
.
Typical error reasons:
einval
does not refer to a symbolic link
or the name of the file that it refers to does not conform
to the expected encoding.
enoent
The file does not exist.
enotsup
Symbolic links are not supported on this platform.
read_link_all(Name) -> {ok, Filename} | {error, Reason}
Name = name_all()
Filename = filename_all()
Reason = posix() | badarg
Returns {ok,
if
refers to a symbolic link or
{error,
otherwise.
On platforms that do not support symbolic links, the return
value is {error,enotsup}
.
Notice that
can be either a list
or a binary.
Typical error reasons:
einval
does not refer to a symbolic link.
enoent
The file does not exist.
enotsup
Symbolic links are not supported on this platform.
read_link_info(Name) -> {ok, FileInfo} | {error, Reason}
Name = name_all()
FileInfo = file_info()
Reason = posix() | badarg
read_link_info(Name, Opts) -> {ok, FileInfo} | {error, Reason}
Name = name_all()
Opts = [file_info_option()]
FileInfo = file_info()
Reason = posix() | badarg
Works like
read_file_info/1,2
except that if
is a symbolic link, information
about the link is returned in the file_info
record and
the type
field of the record is set to symlink
.
If the option raw
is set, the file server is not called and
only information about local files is returned. Note that this will
break this module's atomicity guarantees as it can race with a
concurrent call to
write_file_info/1,2
If
is not a symbolic link, this function returns
the same result as read_file_info/1
.
On platforms that do not support symbolic links, this function
is always equivalent to read_file_info/1
.
rename(Source, Destination) -> ok | {error, Reason}
Source = Destination = name_all()
Reason = posix() | badarg
Tries to rename the file
to
.
It can be used to move files (and directories) between
directories, but it is not sufficient to specify
the destination only. The destination filename must also be
specified. For example, if bar
is a normal file and
foo
and baz
are directories,
rename("foo/bar", "baz")
returns an error, but
rename("foo/bar", "baz/bar")
succeeds. Returns
ok
if it is successful.
Note!
Renaming of open files is not allowed on most platforms
(see eacces
below).
Typical error reasons:
eacces
Missing read or write permissions for the parent
directories of
or
. On
some platforms, this error is given if either
or
is open.
eexist
is not an empty directory.
On some platforms, also given when
and
are not of the same type.
einval
is a root directory, or
is a subdirectory of
.
eisdir
is a directory, but
is not.
enoent
Source
does not exist.
enotdir
is a directory, but
is not.
exdev
and
are on different file systems.
script(Filename) -> {ok, Value} | {error, Reason}
Filename = name_all()
Value = term()
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}
Reads and evaluates Erlang expressions, separated by '.' (or ',', a sequence of expressions is also an expression), from the file.
Returns one of the following:
{ok, Value }
The file is read and evaluated.
is
the value of the last expression.
{error, atom()}
An error occurred when opening the file or reading it.
For a list of typical error codes, see
open/2
.
{error, {Line , Mod ,
Term }}
An error occurred when interpreting the Erlang
expressions in the file. Use
format_error/1
to convert the three-element tuple to an English description
of the error.
The encoding of
can be set
by a comment as described in
epp(3)
.
script(Filename, Bindings) -> {ok, Value} | {error, Reason}
Filename = name_all()
Bindings = erl_eval:binding_struct()
Value = term()
Reason =
posix() |
badarg | terminated | system_limit |
{Line :: integer(), Mod :: module(), Term :: term()}
The same as script/1
but the variable bindings
are used in the evaluation. See
erl_eval(3)
about
variable bindings.
sendfile(Filename, Socket) ->
{ok, integer() >= 0} |
{error, inet:posix() | closed | badarg | not_owner}
Filename = name_all()
Socket = inet:socket()
Sends the file Filename
to Socket
.
Returns {ok, BytesSent}
if successful,
otherwise {error, Reason}
.
sendfile(RawFile, Socket, Offset, Bytes, Opts) ->
{ok, integer() >= 0} |
{error, inet:posix() | closed | badarg | not_owner}
RawFile = fd()
Socket = inet:socket()
Offset = Bytes = integer() >= 0
Opts = [sendfile_option()]
sendfile_option() =
{chunk_size, integer() >= 0} | {use_threads, boolean()}
Sends Bytes
from the file
referenced by RawFile
beginning at Offset
to
Socket
.
Returns {ok, BytesSent}
if successful,
otherwise {error, Reason}
. If Bytes
is set to
0
all data after the specified Offset
is sent.
The file used must be opened using the raw
flag, and the process
calling sendfile
must be the controlling process of the socket.
See gen_tcp:controlling_process/2
.
If the OS used does not support non-blocking sendfile
, an
Erlang fallback using read/2
and gen_tcp:send/2
is
used.
The option list can contain the following options:
chunk_size
The chunk size used by the Erlang fallback to send data. If using the fallback, set this to a value that comfortably fits in the systems memory. Default is 20 MB.
set_cwd(Dir) -> ok | {error, Reason}
Sets the current working directory of the file server to
. Returns ok
if successful.
The functions in the module file
usually treat binaries
as raw filenames, that is, they are passed "as is" even when the
encoding of the binary does not agree with
native_name_encoding()
.
However, this function expects binaries to be encoded according to the
value returned by native_name_encoding()
.
Typical error reasons are:
enoent
The directory does not exist.
enotdir
A component of
is not a directory.
On some platforms, enoent
is returned.
eacces
Missing permission for the directory or one of its parents.
badarg
has an improper type,
such as tuple.
no_translation
is a binary()
with
characters coded in ISO-latin-1 and the VM is operating
with unicode filename encoding.
Warning!
In a future release, a bad type for argument
will probably generate an exception.
sync(IoDevice) -> ok | {error, Reason}
IoDevice = io_device()
Reason = posix() | badarg | terminated
Ensures that any buffers kept by the operating system (not by the Erlang runtime system) are written to disk. On some platforms, this function might have no effect.
A typical error reason is:
enospc
Not enough space left to write the file.
truncate(IoDevice) -> ok | {error, Reason}
IoDevice = io_device()
Reason = posix() | badarg | terminated
Truncates the file referenced by
at
the current position. Returns ok
if successful,
otherwise {error,
.
write(IoDevice, Bytes) -> ok | {error, Reason}
IoDevice = io_device() | atom()
Bytes = iodata()
Reason = posix() | badarg | terminated
Writes
to the file referenced by
. This function is the only way to write to a
file opened in raw
mode (although it works for normally opened
files too). Returns ok
if successful, and
{error,
otherwise.
If the file is opened with encoding
set to something else than
latin1
, each byte written can result in many bytes being written to
the file, as the byte range 0..255 can represent anything between one and
four bytes depending on value and UTF encoding type.
Typical error reasons:
ebadf
The file is not opened for writing.
enospc
No space is left on the device.
write_file(Filename, Bytes) -> ok | {error, Reason}
Filename = name_all()
Bytes = iodata()
Reason = posix() | badarg | terminated | system_limit
Writes the contents of the iodata
term
to file
.
The file is created if it does not exist.
If it exists, the previous contents are overwritten.
Returns ok
if successful, otherwise
{error,
.
Typical error reasons:
enoent
A component of the filename does not exist.
enotdir
A component of the filename is not a directory. On some
platforms, enoent
is returned instead.
enospc
No space is 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.
write_file(Filename, Bytes, Modes) -> ok | {error, Reason}
Filename = name_all()
Bytes = iodata()
Modes = [mode()]
Reason = posix() | badarg | terminated | system_limit
Same as write_file/2
, but takes a third argument
, a list of possible modes, see
open/2
. The mode flags
binary
and write
are implicit, so they are
not to be used.
write_file_info(Filename, FileInfo) -> ok | {error, Reason}
Filename = name_all()
FileInfo = file_info()
Reason = posix() | badarg
write_file_info(Filename, FileInfo, Opts) -> ok | {error, Reason}
Filename = name_all()
Opts = [file_info_option()]
FileInfo = file_info()
Reason = posix() | badarg
Changes file information. Returns ok
if successful,
otherwise {error,
.
is a record
file_info
, defined in the Kernel include file
file.hrl
. Include the following directive in the module
from which the function is called:
-include_lib("kernel/include/file.hrl").
The time type set in atime
, mtime
, and ctime
depends on the time type set in Opts :: {time, Type}
as
follows:
local
Interprets the time set as local.
universal
Interprets it as universal time.
posix
Must be seconds since or before Unix time epoch, which is 1970-01-01 00:00 UTC.
Default is {time, local}
.
If the option raw
is set, the file server is not called
and only information about local files is returned.
The following fields are used from the record, if they are specified:
atime =
date_time()
|
integer() >= 0
The last time the file was read.
mtime =
date_time()
|
integer() >= 0
The last time the file was written.
ctime =
date_time()
|
integer() >= 0
On Unix, any value specified for this field is ignored (the "ctime" for the file is set to the current time). On Windows, this field is the new creation time to set for the file.
mode = integer() >= 0
The file permissions as the sum of the following bit values:
8#00400
Read permission: owner
8#00200
Write permission: owner
8#00100
Execute permission: owner
8#00040
Read permission: group
8#00020
Write permission: group
8#00010
Execute permission: group
8#00004
Read permission: other
8#00002
Write permission: other
8#00001
Execute permission: other
16#800
Set user id on execution
16#400
Set group id on execution
On Unix platforms, other bits than those listed above may be set.
uid = integer() >= 0
Indicates the file owner. Ignored for non-Unix file systems.
gid = integer() >= 0
Gives the group that the file owner belongs to. Ignored for non-Unix file systems.
Typical error reasons:
eacces
Missing search permission for one of the parent directories of the file.
enoent
The file does not exist.
enotdir
A component of the filename is not a directory. On some
platforms, enoent
is returned instead.
POSIX Error Codes
eacces
- Permission deniedeagain
- Resource temporarily unavailableebadf
- Bad file numberebusy
- File busyedquot
- Disk quota exceededeexist
- File already existsefault
- Bad address in system call argumentefbig
- File too largeeintr
- Interrupted system calleinval
- Invalid argumenteio
- I/O erroreisdir
- Illegal operation on a directoryeloop
- Too many levels of symbolic linksemfile
- Too many open filesemlink
- Too many linksenametoolong
- Filename too longenfile
- File table overflowenodev
- No such deviceenoent
- No such file or directoryenomem
- Not enough memoryenospc
- No space left on deviceenotblk
- Block device requiredenotdir
- Not a directoryenotsup
- Operation not supportedenxio
- No such device or addresseperm
- Not ownerepipe
- Broken pipeerofs
- Read-only file systemespipe
- Invalid seekesrch
- No such processestale
- Stale remote file handleexdev
- Cross-domain link
Performance
For increased performance, raw files are recommended.
A normal file is really a process so it can be used as an I/O
device (see io
).
Therefore, when data is written to a normal file, the sending of the
data to the file process, copies all data that are not binaries. Opening
the file in binary mode and writing binaries is therefore recommended.
If the file is opened on another node, or if the file server runs as
slave to the file server of another node, also binaries are copied.
Note!
Raw files use the file system of the host machine of the node. For normal files (non-raw), the file server is used to find the files, and if the node is running its file server as slave to the file server of another node, and the other node runs on some other host machine, they can have different file systems. However, this is seldom a problem.
open/2
can be given the
options delayed_write
and read_ahead
to turn on caching,
which will reduce the number of operating system calls and greatly
improve performance for small reads and writes. However, the overhead
won't disappear completely and it's best to keep the number of file
operations to a minimum. As a contrived example, the following function
writes 4MB in 2.5 seconds when tested:
create_file_slow(Name) -> {ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]), create_file_slow_1(Fd, 4 bsl 20), file:close(Fd). create_file_slow_1(_Fd, 0) -> ok; create_file_slow_1(Fd, M) -> ok = file:write(Fd, <<0>>), create_file_slow_1(Fd, M - 1).
The following functionally equivalent code writes 128 bytes per call
to write/2
and so does the
same work in 0.08 seconds, which is roughly 30 times faster:
create_file(Name) -> {ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]), create_file_1(Fd, 4 bsl 20), file:close(Fd), ok. create_file_1(_Fd, 0) -> ok; create_file_1(Fd, M) when M >= 128 -> ok = file:write(Fd, <<0:(128)/unit:8>>), create_file_1(Fd, M - 128); create_file_1(Fd, M) -> ok = file:write(Fd, <<0:(M)/unit:8>>), create_file_1(Fd, M - 1).
When writing data it's generally more efficient to write a list of
binaries rather than a list of integers. It is not needed to
flatten a deep list before writing. On Unix hosts, scatter output,
which writes a set of buffers in one operation, is used when
possible. In this way write(FD, [Bin1, Bin2 | Bin3])
writes the contents of the binaries without copying the data
at all, except for perhaps deep down in the operating system
kernel.
Warning!
If an error occurs when accessing an open file with module
io
, the process
handling the file exits. The dead file process can hang if a process
tries to access it later. This will be fixed in a future release.