在File.write上接收:badarg

时间:2015-05-14 00:23:30

标签: elixir

我开始学习Elixir,这也是我的第一个动态语言,所以我真的失去了没有类型声明的函数。

我想做什么:
def create_training_data(file_path, indices_path, result_path) do
    file_path
    |> File.stream!
    |> Stream.with_index
    |> filter_data_with_indices(indices_path)
    |> create_output_file(result_path)
  end

  def filter_data_with_indices(raw_data, indices_path) do
    Stream.filter raw_data, fn {_elem, index} ->
      index_match?(index, indices_path)
    end
  end

  defp index_match?(index, indices_path) do
    indices_path
    |> File.stream!
    |> Enum.any? fn elem ->
      (elem
      |> String.replace(~r/\n/, "")
      |> String.to_integer
      |> (&(&1 == index)).())
    end
  end

  defp create_output_file(data, path) do
    File.write(path, data)
  end

当我调用该函数时:

create_training_data("./resources/data/usps.csv","./resources/indices/17.csv","./output.txt")

返回{:error,:badarg}。我已经检查过,错误发生在create_output_file函数上。

如果我注释掉函数create_output_file,我得到的是一个流(有点意义)。问题可能是我不能给Stream to File.write吗?如果是问题,我该怎么办?我在文档中没有找到任何相关内容。

修改

所以,问题是File.write的路径应该没问题,我修改了这个函数:

defp create_output_file(data, path) do
    IO.puts("You are trying to write to: " <> path)
    File.write(path, data)
end

现在再次尝试使用这些参数运行时:

iex(3)> IaBay.DataHandling.create_training_data("/home/lhahn/data/usps.csv", "/home/lhahn/indices/17.csv", "/home/lhahn/output.txt")
You are trying to write to: /home/lhahn/output.txt
{:error, :badarg}
iex(4)> File.write("/home/lhahn/output.txt", "Hello, World")
:ok

所以,我仍然遇到:badarg问题,也许我传递的内容不对?

2 个答案:

答案 0 :(得分:1)

您要写的目录是否存在?我会试试这个:

defp create_output_file(data, path) do
  File.mkdir_p!(Path.dirname(path))
  File.write!(path, data)
end

答案 1 :(得分:1)

首先:您将元组提供给写入。您必须首先从中提取数据:

file_path
|> File.stream!
|> Stream.with_index
|> filter_data_with_indices(indices_path)
|> Stream.map(fn {x,y} -> x end)    # <------------------ here
|> create_output_file(result_path)

第二件事:

看起来你无法将Stream输入File.write / 2,因为它需要iodata。如果您在写入之前将流转换为列表,一切顺利:

defp create_output_file(data, path) do
  data = Enum.to_list(data)
  :ok = File.write(path, data)
end