2011-02-05 17 views
6

Por ejemplo, tengo un archivo txt con 10 cadena de texto. ¿Cómo puedo leer las primeras 5 cuerdas de este texto con erlang?Erlang leer desde el archivo de las primeras 5 filas

Gracias.

+0

@OP : Se le solicita que acepte una respuesta, si alguna de las respuestas publicadas responde a su pregunta y está satisfecho con esto. – Arunmu

+0

@ArunMu: Un usuario verá el comentario, agregado a su publicación, incluso si no hay '@' delante del nick. ;-) –

Respuesta

8

Probablemente desea una combinación de file:open/2 y file:read_line/1 con activar el almacenamiento en búfer.

Una rima:

$ cat mary_lamb.txt 
Mary had a little lamb, 
little lamb, little lamb, 
Mary had a little lamb, 
whose fleece was white as snow. 
And everywhere that Mary went, 
Mary went, Mary went, 
and everywhere that Mary went, 
the lamb was sure to go. 

archivo Fuente:

$ cat ./read_n_lines.erl 
-module(read_n_lines). 
-export([read_n_lines/2]). 

read_n_lines(Filename,NumLines) -> 
    {ok, FileDev} = file:open(Filename, 
      [raw, read, read_ahead]), 
    Lines = do_read([],FileDev, NumLines), 
    file:close(FileDev), 
    Lines. 

do_read(Lines, _, 0) -> 
    lists:reverse(Lines); 
do_read(Lines, FileDev, L) -> 
    case file:read_line(FileDev) of 
      {ok, Line} -> 
       do_read([Line|Lines], FileDev, L - 1); 
      eof -> 
       do_read(Lines, FileDev, 0) 
    end. 

raw, en Modes, se pasa a la file:open/2, permite un acceso más rápido a un archivo, ya que no se necesita ningún proceso de Erlang para manejar la archivo.

de ejecución de la muestra:

$ erl 
1> c(read_n_lines). 
{ok,read_n_lines} 
2> Lines = read_n_lines:read_n_lines("./mary_lamb.txt", 5). 
["Mary had a little lamb,\n","little lamb, little lamb,\n", 
"Mary had a little lamb,\n", 
"whose fleece was white as snow.\n", 
"And everywhere that Mary went,\n"] 
3> length(Lines). 
5 
4> read_n_lines:read_n_lines("./mary_lamb.txt", 666). 
["Mary had a little lamb,\n","little lamb, little lamb,\n", 
"Mary had a little lamb,\n", 
"whose fleece was white as snow.\n", 
"And everywhere that Mary went,\n", 
"Mary went, Mary went,\n", 
"and everywhere that Mary went,\n", 
"the lamb was sure to go."] 
5> 

Para eliminar salto de línea de una cadena, puede utilizar string:strip/1,2,3:

5> lists:map(fun(X) -> string:strip(X, right, $\n) end, Lines). 
["Mary had a little lamb,","little lamb, little lamb,", 
"Mary had a little lamb,", 
"whose fleece was white as snow.", 
"And everywhere that Mary went,"] 
6> 
1

uso io módulo de Erlang.

io: leer (FD, '').

Dónde FD es el identificador de archivo.

También por favor haga buscar el doc Erlang para la sintaxis correcta.

Aquí es un código áspera

 
func(FD) -> 
case io:get_line(FD,'') of 
{ok,text}-> 
%%do something, 
func(FD); 
eof -> 
%%exit; 
error-> 
%%quit 
end 

Se puede utilizar un contador si desea procesar sólo 10 líneas

+0

Veo que ha mencionado la cadena o son líneas que tiene la intención de decir? Si se trata de string..then leer la primera línea y tokenize usando el módulo de cadena de Erlang .... o utilizar operaciones de bits estilo de programación funcional clásica :) – Arunmu

+0

Esto lee términos, no cadenas :-) "se lee en un término' Plazo 'desde la entrada estándar (' IoDevice'), solicitándolo con 'Prompt'. –

+0

@Yasir: ohhk ... gracias por hacerme notar que ... he editado mi código ... – Arunmu

2

Otra solución, n_times pueden tener otros usos:

-module(n_times). 

-export([test/0]). 

test() -> 
    io:format("~p~n", [n_lines("n_times.erl", 5)]). 

n_lines(FileName, N) -> 
    {ok, FileDev} = file:open(FileName, [raw, read, read_ahead]), 
    try 
    n_times(fun() -> {ok, L} = file:read_line(FileDev), L end, N) 
    after 
    file:close(FileDev) 
    end. 

n_times(F, N) -> 
    n_times(F, N, []). 

n_times(_, 0, A) -> 
    lists:reverse(A); 
n_times(F, N, A) -> 
    n_times(F, N-1, [F()|A]). 
Cuestiones relacionadas