在上传的文件上操作

时间:2017-12-28 19:57:59

标签: parsing file-upload elixir phoenix-framework

我正在尝试解析上传的文件,如下所示:

lib/thingy_web/controllers/things_controller.ex

  def create(conn, %{"data" => %Plug.Upload{content_type: "application/octet-stream", filename: basename, path: dirname}}) do
    things_params = dirname <> "/" <> basename
    |> File.stream!
    |> NimbleCSV.RFC4180.parse_stream
    |> Enum.map(&AllThings.create_things_params/1)
    |> Enum.map(&AllThings.create_things/1)

    conn
    |> put_status(:created)
  end

但是,当我尝试使用测试文件进行POST时:

curl -F 'data=@/root/test' http://localhost:4000/api/thing

我收到错误:

[debug] Processing with ThingyWebWeb.ThingsController.create/2
  Parameters: %{"data" => %Plug.Upload{content_type: "application/octet-stream", filename: "test", path: "/tmp/plug-1514/multipart-1514490176-65282591343221-1"}}
  Pipelines: [:api]
[info] Sent 500 in 55ms
[error] #PID<0.544.0> running ThingyWeb.Endpoint terminated
Server: localhost:4000 (http)
Request: POST /api/thing
** (exit) an exception was raised:
    ** (File.Error) could not stream "/tmp/plug-1514/multipart-1514490176-65282591343221-1/test": not a directory
        (elixir) lib/file/stream.ex:79: anonymous fn/2 in Enumerable.File.Stream.reduce/3
        (elixir) lib/stream.ex:1270: anonymous fn/5 in Stream.resource/3
        (elixir) lib/stream.ex:806: Stream.do_transform/8

/tmp/plug-1514/的后续检查表明它确实是一个空目录。

上传的文件是否存在时间短,可以配置为长期存在,还是我在这里完全遗漏了某些内容?

1 个答案:

答案 0 :(得分:2)

path包含上传文件的完整路径。 filename只是用户在浏览器中选择的文件的名称(或者在本例中为curl);上传的文件不会以该名称存储。您只需将path传递给File.stream!/1

things_params =
  path
  |> File.stream!
  |> ...