как считать содержание файла В Erlang?

Я знаю, что можно сделать что-то вроде этого:

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, который может сделать это также?

13
задан N 1.1 19 March 2010 в 07:29
поделиться

1 ответ

file:read_file/1 - это то, что вы ищете. Просто для обучения, Accum ++ [Line] - плохая практика. Проблема в том, что левый аргумент ++ копируется, а правый используется как есть. В вашем коде вы будете копировать все большую и большую часть в каждой итерации. Решением является lists:reverse(Line,Accum) и затем возврат lists:reverse(Accum) в ветке eof (Или [Line|Accum] и lists: append(lists:reverse(Accum)) в eof или используйте бинарники с лучшей операцией append или ...). ..). Другой способ - не использовать хвостовую рекурсивную функцию, что не так плохо, как кажется на первый взгляд, согласно Миф: Хвостовые рекурсивные функции намного быстрее рекурсивных.

Итак, ваша функция 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.
29
ответ дан 1 December 2019 в 19:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: