2010-01-31 61 views
9

從讀取文本文件到erlang中的二進制字符串列表所用時間的最有效方式是什麼?明顯的解決方案將文件讀入字符串列表的最有效方式

-module(test). 
-export([run/1]). 

open_file(FileName, Mode) -> 
    {ok, Device} = file:open(FileName, [Mode, binary]), 
    Device. 

close_file(Device) -> 
    ok = file:close(Device). 

read_lines(Device, L) -> 
    case io:get_line(Device, L) of 
     eof -> 
      lists:reverse(L); 
     String -> 
      read_lines(Device, [String | L]) 
    end. 

run(InputFileName) -> 
    Device = open_file(InputFileName, read), 
    Data = read_lines(Device, []), 
    close_file(Device), 
    io:format("Read ~p lines~n", [length(Data)]). 

當文件包含超過100000行時變得太慢。

+1

你爲什麼要將讀取的內容傳遞給get_line作爲提示? – Zed 2010-01-31 14:09:08

+0

@Zed,那是我的錯。現在所有人都以可接受的速度工作。謝謝!有時候我希望erlang擁有一個強大的類型系統...... – Konstantin 2010-01-31 22:32:53

回答

15
{ok, Bin} = file:read_file(Filename). 

,或者如果您通過線所需要的內容,行

read(File) -> 
    case file:read_line(File) of 
     {ok, Data} -> [Data | read(File)]; 
     eof  -> [] 
    end. 
2

在成二進制讀取整個文件。轉換爲列表並翻出行。

這比任何其他方法效率更高。如果你不相信我時間 它。

 
file2lines(File) -> 
    {ok, Bin} = file:read_file(File), 
    string2lines(binary_to_list(bin), []). 

string2lines("\n" ++ Str, Acc) -> [reverse([$\n|Acc]) | string2lines(Str,[])]; 
string2lines([H|T], Acc)  -> string2lines(T, [H|Acc]); 
string2lines([], Acc)   -> [reverse(Acc)]. 
相關問題