Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Stream Elixir:如何跨多个管道保持流状态?_Stream_Elixir - Fatal编程技术网

Stream Elixir:如何跨多个管道保持流状态?

Stream Elixir:如何跨多个管道保持流状态?,stream,elixir,Stream,Elixir,我的目标:我想读取文件的第一行,在管道中重新构造输入,然后在另一个管道中处理文件的其余部分 我的问题:流在每个新管道上重置 示例代码: defmodule StrangeStream do fs = File.stream!("file.txt") Stream.take(fs, 1) |> Enum.to_list() |> IO.inspect() Stream.take(fs, 1) |> Enum.to_list() |> IO.inspect()

我的目标:我想读取文件的第一行,在管道中重新构造输入,然后在另一个管道中处理文件的其余部分

我的问题:流在每个新管道上重置

示例代码

defmodule StrangeStream do
  fs = File.stream!("file.txt")

  Stream.take(fs, 1) |> Enum.to_list() |> IO.inspect()

  Stream.take(fs, 1) |> Enum.to_list() |> IO.inspect()
end
First line.
Second line.
Third line.
["First line.\n"]
["First line.\n"]
文本文件
file.txt

defmodule StrangeStream do
  fs = File.stream!("file.txt")

  Stream.take(fs, 1) |> Enum.to_list() |> IO.inspect()

  Stream.take(fs, 1) |> Enum.to_list() |> IO.inspect()
end
First line.
Second line.
Third line.
["First line.\n"]
["First line.\n"]
输出

defmodule StrangeStream do
  fs = File.stream!("file.txt")

  Stream.take(fs, 1) |> Enum.to_list() |> IO.inspect()

  Stream.take(fs, 1) |> Enum.to_list() |> IO.inspect()
end
First line.
Second line.
Third line.
["First line.\n"]
["First line.\n"]

如您所见,流在每个管道中重置。每个管道从文件中的第一行开始。如何在对管道的调用之间保持流的状态?提前谢谢

TL;博士:你不能


中没有可变状态,因此不可能维护资源的状态

唯一类似的事情是在减少过程中枚举,但即使是直接使用流也不可能做到这一点

您可以自己使用并维护状态,并相应地选择管道


旁注:
Enum.to_list/1
已经终止了一个流,因此问题中的方法根本不起作用。

以下是我如何获得想要的效果的。希望它能帮助其他研究此问题的人

再次感谢Aleksei为我节省了这么多时间

defmodule StrangeStream do
  do_stuff = fn(something) ->
    # We'd do something useful here
    something
  end

  {:ok, file} = File.open("file.txt", [:read, :line])

  # Read the first line
  first_line = IO.read(file, :line)
  |>  String.trim()
  |>  do_stuff.()
  |>  IO.inspect([label: "first_line"])

  # Create side-effect streams
  print_stream = IO.binstream(:stdio, :line)
  file_stream  = File.stream!("output.txt", [:write, :append])

  # Convert IO to Stream and process
  IO.stream(file, :line)
  |>  Stream.map(&String.trim(&1))
  |>  do_stuff.()
  |>  Stream.into(print_stream, fn(s)-> s <>"\n" end)
  |>  do_stuff.()
  |>  Stream.into(file_stream)
  |>  do_stuff.()
  |>  Enum.to_list()
  |>  IO.inspect([label: "rest of file"])
end

感谢Aleksei让我走上了正确的道路。