How to read from post param?

丶灬走出姿态 提交于 2019-12-25 02:44:11

问题


I need to parse text file. This file is in post param. I have code like this:

upload_file('POST', []) ->
    File = Req:post_param("file"),

What should I do next? How to parse it?


回答1:


What's inside Req:post_param("file") ?

You assume it's a path to a file: have you checked the value of File ?

Anyway, it's Req:post_files/0 you are probably looking for:

[{_, _FileName, TempLocation, _Size}|_] = Req:post_files(),
{ok,Data} = file:read_file(TempLocation),

It's also probably a Bad Idea to leave the file at it's temporary location, you'd better find a more suitable place to store them.


It seems the uploaded_file record has 5 fields now (for 10 months by now).

This is the updated example, with the fifth field:

[{_, _FileName, TempLocation, _Size, _Name}|_] = Req:post_files(),
{ok,Data} = file:read_file(TempLocation),

Oh, and because it's a record, following example should work even if the definition gets updated once again:

[File|_] = Req:post_files(),
{ok,Data} = file:read_file(File#uploaded_file.temp_file),

Another warning: the code above, as any erlanger will see, only deals with the first and, probably most of the times, only uploaded file. Should more files be uploaded at the same time, these would be ignored.




回答2:


The answer really depend on the content of "File". for example if the file content a string with respecting erlang syntax such as:

[{{20,4},0},
 {{10,5},0},
 {{24,1},0},
 {{22,1},0},
 {{10,6},0}].

can be read with this code:

File = Req:post_param("file"),
{ok,B} = file:read_file(File),
{ok,Tokens,_} = erl_scan:string(binary_to_list(B)),
{ok,Term} = erl_parse:parse_term(Tokens),
%% at this point Term = [{{20,4},0},{{10,5},0},{{24,1},0},{{22,1},0},{{10,6},0}]

[Edit]

the Erlang libraries use most of the time tuple as return value. It can help to manage the normal case and error cases. In the previous code, all lines are "pattern matched" to the success case only. That means that it will crash if any of the operation fails. If the surrounding code cath the error you will be able to manage the error case, otherwise the process will simply die reporting a badmatch error.

I chose this implementation because at this level of code, there is nothing that can be done to deal with an error. {{badmatch,{error,enoent}} simply means that the return value of file:read_file(File) is not of the form {ok,B} as expected, but is {error,enoent}, which means that the file File does not exist in the current path.

extract of the documentation

read_file(Filename) -> {ok, Binary} | {error, Reason}
Types:
Filename = name()
Binary = binary()
Reason = posix() | badarg | terminated | system_limit

Returns {ok, Binary}, where Binary is a binary data object that contains the contents of Filename, or {error, Reason} if an error occurs.

Typical error reasons:
enoent
    The file does not exist.
eacces
    Missing permission for reading the file, or for searching one of the parent directories.
eisdir
    The named file is a directory.
enotdir
    A component of the file name is not a directory. On some platforms, enoent is returned instead.
enomem
    There is not enough memory for the contents of the file.

In my opinion the calling code should manage this case if it is a real use case, for example File comes from a user interface, or let the error unmanaged if this case should not happen. In your case you could do

try File_to_term(Params) % call the above code with significant Params
catch
    error:{badmatch,{error,enoent}} -> file_does_not_exist_management();
    error:{badmatch,{error,eacces}} -> file_access_management();
    error:{badmatch,{error,Error}} -> file_error(Error)
end


来源:https://stackoverflow.com/questions/20738391/how-to-read-from-post-param

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!