Files and IO
| File.read | |
| File.write | |
| Stream lines | |
| Path joins |
File.read
The File.read function returns an ok tuple with the whole content or an error tuple with the reason. Matching both shapes with case keeps missing files from crashing the program. Small config files and notes fit this shape well.
File.write!("notes.txt", "hello\n")
case File.read("notes.txt") do
{:ok, data} -> IO.puts(data)
{:error, _reason} -> IO.puts("missing")
end
hello
File.write
The File.write function stores a binary under the given name and returns the atom ok on success. It replaces the whole file, so earlier content is lost. The bang twin raises instead of returning an error tuple.
IO.inspect(File.write("notes.txt", "hello\n"))
:ok
Stream lines
Reading the whole file breaks down on huge logs, so File.stream! opens a lazy enumerable of lines. Enum functions then pull only what they need while the rest stays on disk. Taking two lines never loads the whole file.
File.write!("notes.txt", "a\nb\nc\n")
first_two = Enum.take(File.stream!("notes.txt"), 2)
IO.inspect(first_two)
["a\n", "b\n"]
Path joins
String concatenation guesses separators and breaks across systems, so the Path module joins segments for you. Path.join inserts the right separator while expand resolves home and relative parts. Build every file path this way instead of gluing strings.
IO.puts(Path.join("notes", "a.txt"))
notes/a.txt
Next: Processes
Article author: Arthur Isaev