如何在Erlang中读取文件的内容?

发布于 2024-08-25 23:02:24 字数 367 浏览 3 评论 0原文

我知道你可以做这样的事情:

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

I know you can do something like this:

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.

Is there a one liner BIF that can do this too?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北恋 2024-09-01 23:02:24

file:read_file/1 就是您要查找的内容。仅出于教学目的,Accum ++ [Line] 是不好的做法。问题是 ++ 的左参数被复制,而右参数按原样使用。在您的代码中,您将在每次迭代中复制越来越大的部分。解决方案是 lists:reverse(Line,Accum) ,然后在 eof 分支中返回 lists:reverse(Accum) (或者 [ Line|Accum]lists:append(lists:reverse(Accum))eof 或使用具有更好附加操作的二进制文件或...) 。另一种方法是不使用尾递归函数,根据 神话,它并不像第一次看起来那么糟糕:尾递归函数比递归函数快得多

所以你的 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.

file:read_file/1 is what you are looking for. Just for teaching purpose, Accum ++ [Line] is bad practice. Problem is that left argument of ++ is copied and right is used as is. In your code you will copy bigger and bigger part in each iteration. Solution is lists:reverse(Line,Accum) and than return lists:reverse(Accum) in your eof branch (Or [Line|Accum] and lists:append(lists:reverse(Accum)) at the eof or use binary which have better append operation or ...). Another way is not using tail recursive function which is not so bad as seems at first time according to Myth: Tail-recursive functions are MUCH faster than recursive functions.

So your readlines/1 function should look like

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.
-小熊_ 2024-09-01 23:02:24

您可以利用 file:read_file/1binary:split/3 分两步完成这项工作:

readlines(FileName) ->
    {ok, Data} = file:read_file(FileName),
    binary:split(Data, [<<"\n">>], [global]).

You could leverage file:read_file/1 and binary:split/3 to do this work in two steps:

readlines(FileName) ->
    {ok, Data} = file:read_file(FileName),
    binary:split(Data, [<<"\n">>], [global]).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文