我知道你可以这样做:
readlines(FileName) ->
{ok, Device} = file:open(FileName, [read]),
get_all_lines(Device, []).
get_all_lines(Device, Accum) ->
case io:get_line(Device, "") of
eof -> file:close(Device), Accum;
Line -> get_all_lines(Device, Accum ++ [Line])
end.
:是否有单行BIF可以做到这一点?
答案 0 :(得分:27)
file:read_file/1正是您要找的。仅仅出于教学目的,Accum ++ [Line]
是不好的做法。问题是复制了++
的左参数,并按原样使用了右。在您的代码中,您将在每次迭代中复制越来越大的部分。解决方案为lists:reverse(Line,Accum)
,而不是lists:reverse(Accum)
分支中的eof
,或[Line|Accum]
的{{1}}和lists:append(lists:reverse(Accum))
,或使用更好附加的二进制文件操作或...)。另一种方法是不使用尾递归函数,这种函数不像第一次Myth: Tail-recursive functions are MUCH faster than recursive functions那样糟糕。
所以你的eof
函数看起来应该是
readlines/1
答案 1 :(得分:10)
您可以通过以下两个步骤利用file:read_file/1
和binary:split/3
来完成这项工作:
readlines(FileName) ->
{ok, Data} = file:read_file(FileName),
binary:split(Data, [<<"\n">>], [global]).