2013-01-22 35 views
1

我問了一個類似的問題,不知道什麼不清楚,但我會再試一次。我有一個文件。文件名是file.txt,我將file.txt讀入列表中。現在我可以將其打印到控制檯,它會顯示:文件IO和列表處理

blah 
blah 
blah 
blah 

這很好。完美:)現在我將如何轉發到一個新的文件?使新文件包含:

blah 
blah 
blah 
blah 

沒有更多,也沒有少。這裏是我用來讀取列表中的文件的代碼: {ok,Device} = file:open(「file.txt」,[read]), Li = readdata(Device,[])。

readdata(Device, Accum) -> 
case io:get_line(Device, "") of 
    eof -> file:close(Device), Accum; 
    Line -> readdata(Device, Accum ++ [Line]) 
end. 

如此反覆,以顯示新的文件正是我讀的顯示器,沒有多餘的人物,不是所有的1個line..etc ..一樣的:)

回答

2

好,易文件方法是:

ok = file:write_file("output.txt", Li). 

正如你可以看到http://www.erlang.org/doc/man/file.html,有很多有用的功能,如文件:READ_FILE/1可能會縮短你的程序,並在同一時間讓它更快一點。

您會發現,將讀取數據與累加器組合的方式並不完美,因爲它需要複製累加值,所以讀數據/ 2函數的複雜度爲N^2。追加到列表頭是最好的方法,但是當然你必須將行存儲爲Acc的值並最終反轉它。

那麼文件的長度呢?如果它很大並且不適合記憶,那麼即使正確使用蓄電池,也會遇到問題。這種情況下的標準方法是打開這兩個文件,讀取一些數據塊並立即將其寫入輸出。

copy_file() -> 
    {ok, In} = file:open("input", [read]), 
    {ok, Out} = file:open("output", [write]), 
    copy_file(In, Out), 
    file:close(In), 
    file:close(Out). 

copy_file(In, Out) -> 
    case file:read(In, 1024 * 64) of 
     {ok, Data} -> 
      ok = file:write(Out, Data), 
      copy_file(In, Out); 
     _ -> 
      ok 
    end. 

我沒有試過代碼,它可能不會編譯,我只是試圖展示基本思想。

+0

文件是非常小,在其他語言的簡單,如: '數據[] = file.read( 「file.txt的」)'' 開放= file.open( 「new.txt」)' '的foreach(數據線)'' file.write(開放式,線)'' end' ' 我其實不想「複製」文件中,這僅僅是我使用來解釋該定義我想把數據列表寫到一個新文件中,就像它在另一個文件中出現的一樣。我可能希望修改列表並將其寫回到同一個文件中。因此,複製只是我使用的一個術語。 – ace007

+0

Erlang的列表模塊確實有一個foreach函數,用於處理列表中的副作用。你可以看看。我會嘗試把答案和一些代碼示例一起。 – dsmith

+0

我已經使用foreach,出於某種原因輸出似乎全部在文件中的1行,我試過foreach和映射相同的結果。 – ace007

0

所以這就是我想出的。我稍微修改了readdata/2以優化append並刪除換行符。寫/ 2函數使用列表:foreach/2和io:fwrite/3寫入文件。

-module(rwlist). 
-export([read/1,write/2]). 

read(FileName) -> 
    case file:open(FileName, [read]) of 
     {ok, Device} -> 
     readdata(Device, []) 
    end. 

readdata(Device, Accum) -> 
    case io:get_line(Device, "") of 
     eof -> file:close(Device), lists:reverse(Accum); 
     Line -> readdata(Device, [(Line--"\n")|Accum]) 
    end. 

write(FileName, List) -> 
    case file:open(FileName, [write]) of 
     {ok, Device} -> 
     lists:foreach(fun(Line) -> writeline(Device, Line) end, List), 
     file:close(Device) 
    end. 

writeline(Device, Line) -> writeline(Device, Line, os:type()). 

writeline(Device, Line, {win32,_}) -> io:fwrite(Device, "~s\r\n", [Line]); 
writeline(Device, Line, _) -> io:fwrite(Device, "~s\n", [Line]). 

這裏的測試...

57> List=rwlist:read("list"). 
["item 1","item 2","item 3","item 4"] 
58> rwlist:write("list2", List). 
ok 
59> List2=rwlist:read("list2"). 
["item 1","item 2","item 3","item 4"] 

當然,如果你只是複製文件德米特里的回答是好。

+0

我修改了示例代碼以添加操作系統特定的writeline/2函數,因爲Erlang格式化程序不會爲我們執行此操作。 – dsmith