Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I stream into a file in Elixir?

Tags:

elixir

How do I take a stream and write each line to a file?

Say I have a file of words which I stream in using File.stream!, I do some transform on them (here I'm replacing vowels with underscores), but then I want to write this out to a new file. How do I do that? Best I've got so far is this:

iex(3)> ["hello", "my", "friend"] |> Stream.map(&String.replace(&1, ~r{[aeiou]}, "_")) |> Enum.to_list
["h_ll_", "my", "fr__nd"]
like image 255
Thomas Browne Avatar asked Aug 29 '16 16:08

Thomas Browne


1 Answers

You need to use File.stream! to open a file in streaming mode, and Stream.into and Stream.run to write the data to that file:

iex(1)> file = File.stream!("a.txt")
%File.Stream{line_or_bytes: :line, modes: [:raw, :read_ahead, :binary],
 path: "a.txt", raw: true}
iex(2)> ["hello", "my", "friend"] |> Stream.map(&String.replace(&1, ~r{[aeiou]}, "_")) |> Stream.into(file) |> Stream.run
:ok
iex(3)> File.read!("a.txt")
"h_ll_myfr__nd"

Edit: As @FredtheMagicWonderDog pointed out, it's better to just do |> Enum.into(file) instead of |> Stream.into(file) |> Stream.run.

iex(1)> file = File.stream!("a.txt")
%File.Stream{line_or_bytes: :line, modes: [:raw, :read_ahead, :binary],
 path: "a.txt", raw: true}
iex(2)> ["hello", "my", "friend"] |> Stream.map(&String.replace(&1, ~r{[aeiou]}, "_")) |> Enum.into(file)
%File.Stream{line_or_bytes: :line, modes: [:raw, :read_ahead, :binary],
 path: "a.txt", raw: true}
iex(3)> File.read!("a.txt")
"h_ll_myfr__nd"
like image 175
Dogbert Avatar answered Oct 13 '22 00:10

Dogbert