Writing Files in Elixir

Here’s the translation of the Go code to Elixir, with explanations in Markdown format suitable for Hugo:

Writing files in Elixir follows similar patterns to the ones we saw earlier for reading.

defmodule FileWriter do
  def write_files do
    # To start, here's how to dump a string (or just bytes) into a file.
    content = "hello\nelixir\n"
    File.write("/tmp/dat1", content)

    # For more granular writes, open a file for writing.
    {:ok, file} = File.open("/tmp/dat2", [:write])

    # It's idiomatic to use `try` with `after` to ensure the file is closed
    try do
      # You can write strings as you'd expect.
      IO.write(file, "some\n")
      IO.puts("wrote #{byte_size("some\n")} bytes")

      # Write more content
      IO.write(file, "writes\n")
      IO.puts("wrote #{byte_size("writes\n")} bytes")

      # Elixir uses IO.write for both strings and iodata (list of integers or binaries)
      IO.write(file, [115, 111, 109, 101, 10])
      IO.puts("wrote 5 bytes")

      # `IO` provides buffered writes by default
      IO.write(file, "buffered\n")
      IO.puts("wrote #{byte_size("buffered\n")} bytes")

    after
      # Ensure the file is closed
      File.close(file)
    end
  end
end

FileWriter.write_files()

Try running the file-writing code.

$ elixir writing_files.exs
wrote 5 bytes
wrote 7 bytes
wrote 5 bytes
wrote 9 bytes

Then check the contents of the written files.

$ cat /tmp/dat1
hello
elixir

$ cat /tmp/dat2
some
writes
some
buffered

In Elixir, file operations are handled by the File module, and IO operations are handled by the IO module. The language provides built-in buffering for file operations, so there’s no need for an explicit buffered writer like in some other languages.

Error handling in Elixir is typically done using pattern matching and the case expression, or by allowing processes to crash and be restarted by supervisors. In this example, we’ve kept it simple by not including explicit error handling.

Next, we’ll look at applying some of the file I/O ideas we’ve just seen to the standard input and output streams.