Skip to content
I/O and File Operations
step 1/7

Reading — step 1 of 7

Learn

~2 min readHigher-Order Functions, BIFs, and IO

Erlang's I/O is straightforward but has its own conventions. The io module handles standard I/O; file handles disk; binary is for raw bytes.

Reading input

%% Read a line (returns line including trailing newline):
Line = io:get_line("")        %% prompt is empty for stdin

%% Trim and parse:
N = list_to_integer(string:trim(io:get_line("")))

%% Read all of stdin:
io:get_chars("", 65536)

io:get_line returns the line WITH the trailing \n. Use string:trim/1 to strip whitespace.

Writing output

io:format("hello~n")                       %% hello + newline
io:format("name: ~s, age: ~p~n", [N, A])   %% formatted
io:format("~w~n", [Term])                  %% write term in canonical form
io:fwrite(...)                              %% same as io:format

Format specifiers:

  • ~p — print, pretty
  • ~w — write, canonical (machine-readable)
  • ~s — string (list of characters)
  • ~b — base-10 integer
  • ~e — float, scientific
  • ~f — float, decimal
  • ~B — binary
  • ~n — newline (preferred over \n for portability)

Reading a whole file

{ok, Bin} = file:read_file("data.txt"),
Text = binary_to_list(Bin)         %% if you need a string

Files are returned as binaries by default. For text processing, decide whether you want binary or list-of-chars.

Writing files

file:write_file("out.txt", "hello world\n")
file:write_file("out.txt", io_lib:format("~p~n", [Term]))

Note: io_lib:format returns an io_list (a deeply-nested list). file:write_file flattens it for you.

Line-by-line

process_file(Path) ->
    {ok, Fd} = file:open(Path, [read]),
    process_lines(Fd),
    file:close(Fd).

process_lines(Fd) ->
    case io:get_line(Fd, "") of
        eof -> ok;
        Line ->
            io:format("got: ~s", [Line]),
            process_lines(Fd)
    end.

Check for eof to terminate the loop.

Standard error

io:format(standard_error, "bad: ~p~n", [Reason])

First argument to io:format can be a device. standard_io (default) and standard_error are pre-opened.

io_lib:format vs io:format

io:format("hello ~p~n", [42]).         %% prints; returns ok
Str = io_lib:format("hello ~p~n", [42]). %% returns iolist for later use

Use io_lib:format when you want to compose strings, then send them somewhere later (file, log, etc.).

Common mistakes

  • Forgetting to trim io:get_line — the trailing newline is included.
  • Using \n instead of ~n — ~n is portable (handles \r\n on Windows). \n is just LF.
  • Mixing strings and binaries — file operations default to binaries; io:format defaults to strings. Convert explicitly.
  • Reading huge files with file:read_file — loads everything into memory. For big files, use file:open + io:get_line in a loop.
  • Not closing files — file:close/1 is essential. For exception safety, use try/after or a higher-level wrapper.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…