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"]
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With