Reading Files in Erlang

Our first example demonstrates reading files in Erlang. Reading files is a common task in many programs, so let’s explore various ways to do this.

-module(reading_files).
-export([main/0]).

% Helper function to handle errors
check(ok) -> ok;
check({error, Reason}) -> erlang:error(Reason).

main() ->
    % Read entire file contents into memory
    {ok, Data} = file:read_file("/tmp/dat"),
    io:format("~s", [Data]),

    % Open a file for more controlled reading
    {ok, File} = file:open("/tmp/dat", [read]),

    % Read some bytes from the beginning of the file
    {ok, B1} = file:read(File, 5),
    io:format("~B bytes: ~s~n", [length(B1), B1]),

    % Seek to a known location and read from there
    {ok, _} = file:position(File, 6),
    {ok, B2} = file:read(File, 2),
    io:format("~B bytes @ ~B: ~s~n", [length(B2), 6, B2]),

    % Seek relative to current position
    {ok, _} = file:position(File, {cur, 4}),

    % Seek relative to end of file
    {ok, _} = file:position(File, {eof, -10}),

    % Read exactly 2 bytes (similar to io.ReadAtLeast)
    {ok, _} = file:position(File, 6),
    {ok, B3} = file:read(File, 2),
    io:format("~B bytes @ ~B: ~s~n", [length(B3), 6, B3]),

    % Rewind to the beginning of the file
    {ok, _} = file:position(File, bof),

    % Use file:read_line for efficient line-by-line reading
    {ok, Line} = file:read_line(File),
    io:format("~B bytes: ~s", [length(Line), Line]),

    % Close the file when done
    ok = file:close(File).

To run this program, save it as reading_files.erl and use the Erlang shell:

$ echo "hello" > /tmp/dat
$ echo "erlang" >> /tmp/dat
$ erl
1> c(reading_files).
{ok,reading_files}
2> reading_files:main().
hello
erlang
5 bytes: hello
2 bytes @ 6: er
2 bytes @ 6: er
6 bytes: hello

This example demonstrates various file reading operations in Erlang:

  1. Reading an entire file into memory using file:read_file/1.
  2. Opening a file for more controlled reading with file:open/2.
  3. Reading a specific number of bytes with file:read/2.
  4. Seeking to different positions in the file using file:position/2.
  5. Reading lines efficiently with file:read_line/1.
  6. Proper error handling and file closing.

Erlang’s built-in file module provides these file I/O operations. Unlike Go, Erlang doesn’t have a separate buffered I/O module, as file operations are generally buffered by default for efficiency.

Remember to always close files when you’re done with them to free up system resources.

Next, we’ll look at writing files in Erlang.