2013-01-22 37 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