2011-02-05 14 views
6

Na przykład mam plik txt z 10 ciągami tekstu. Jak mogę przeczytać pierwszy 5 ciąg tego tekstu z erlang?Erlang odczytał z pliku pierwsze 5 wierszy

Dziękuję.

+0

@OP : Jesteś poproszony o zaakceptowanie odpowiedzi, jeśli którakolwiek z przesłanych odpowiedzi odpowiada na twoje pytanie, a ty jesteś zadowolony to. – Arunmu

+0

@ArunMu: Użytkownik zobaczy komentarz dodany do jego (jej) wpisu, nawet jeśli przed nickiem nie ma znaku "@". ;-) –

Odpowiedz

8

Prawdopodobnie chcesz kombinacji file:open/2 i file:read_line/1 z włączone buforowanie.

wierszyk:

$ 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. 

Plik źródłowy:

$ 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 w Modes, przeszedł do file:open/2, pozwala na szybszy dostęp do pliku, ponieważ żaden proces Erlang jest potrzebne do obsługi plik.

run Próbka:

$ 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> 

Aby usunąć znak nowej linii z ciągiem, można użyć 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

używać modułu io erlang.

io: odczyt (FD, ").

Gdzie FD jest uchwytem pliku.

Proszę również sprawdzić dokument erlang dla poprawnej składni.

Oto kod szorstki

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

Można użyć licznika, jeśli chcesz, aby przetwarzać tylko 10 linii

+0

Widzę, że wspomniałeś ciąg lub czy to linie, które zamierzałeś powiedzieć? Jeśli jest string ... czytaj pierwszą linię i tokenize za pomocą modułu string z erlang .... lub użyj operacji bitowych klasyczny funkcjonalny styl programowania :) – Arunmu

+0

To czyta terminy, a nie ciągi znaków :-) "Czyta termin" Term 'ze standardowego wejścia (' IoDevice'), prosząc go 'Prompt'." –

+0

@ Yasir: ohhk ... dzięki za zwrócenie mi uwagi na to, że edytowałem mój kod ... – Arunmu

2

Innym rozwiązaniem, n_times mogą być wykorzystywane gdzie indziej:

-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]). 
Powiązane problemy