Reputation: 24888
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"]
Upvotes: 10
Views: 7228
Reputation: 222188
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"
Upvotes: 18