2010-03-19 15 views
11

Sé que usted puede hacer algo como esto:cómo leer el contenido de un archivo En 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. 

: ¿Hay una BIF revestimiento que puede hacer esto también?

Respuesta

23

file:read_file/1 es lo que busca. Solo con fines didácticos, Accum ++ [Line] es una mala práctica. El problema es que el argumento de la izquierda de ++ se copia y el derecho se usa tal cual. En tu código, copiarás partes cada vez más grandes en cada iteración. La solución es lists:reverse(Line,Accum) y que devuelve lists:reverse(Accum) en su rama eof (O [Line|Accum] y en el eof o utilice el binario que tenga una mejor operación de adición o ...). Otra forma de cola no está utilizando la función recursiva que no es tan malo como parece a primera hora de acuerdo a Myth: Tail-recursive functions are MUCH faster than recursive functions.

lo tanto, su función readlines/1 debe ser similar

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. 
+0

Ok, gracias, un buen consejo! – Zubair

+0

¿No es un archivo: read_file un poco peligroso? Quiero decir que está usando file_server que parece que está bloqueando (gen_server que está envolviendo el archivo prim). Parece que archivo_primario o archivo_io_servidor podrían ser mejores soluciones. – mkorszun

+0

No he experimentado ni escuchado ningún problema con 'file: read_file'. No entiendo lo que debería bloquear. –

9

Se podría aprovechar file:read_file/1 y binary:split/3 para hacer este trabajo en dos pasos:

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

Realmente desea hacer una declaración de caso aquí, porque el archivo no podría existir. archivo de caso: read_file (FileName) de {ok, Data} -> ... {error, _} -> ... end. –

Cuestiones relacionadas