我知道您可以执行以下操作:

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也可以做到这一点?

最佳答案

file:read_file/1是您要寻找的。仅出于教学目的,Accum ++ [Line]是不好的做法。问题是++的left参数被复制而right被原样使用。在您的代码中,您将在每次迭代中复制越来越大的部分。解决方案是lists:reverse(Line,Accum),而不是在lists:reverse(Accum)分支中返回eof(或者在[Line|Accum]处使用lists:append(lists:reverse(Accum))eof或使用具有更好附加操作的二进制文件或...)。另一种方法是不使用尾递归函数,该函数并不像第一次出现时那样糟糕,根据Myth: Tail-recursive functions are MUCH faster than recursive functions

所以您的readlines/1函数应该看起来像

readlines(FileName) ->
    {ok, Device} = file:open(FileName, [read]),
    try get_all_lines(Device)
      after file:close(Device)
    end.

get_all_lines(Device) ->
    case io:get_line(Device, "") of
        eof  -> [];
        Line -> Line ++ get_all_lines(Device)
    end.

关于erlang - 如何在Erlang中读取文件的内容?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2475270/

10-09 17:47