我问了一个类似的问题,不知道有什么不清楚,但我会再试一次。我有一个文件。文件名是file.txt,我将file.txt读入列表。现在我可以将它打印到控制台,它将显示:
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行......等等...:
答案 0 :(得分:2)
嗯,简单的方法是:
ok = file:write_file("output.txt", Li).
正如您在http://www.erlang.org/doc/man/file.html中看到的那样,有很多有用的函数,例如file:read_file / 1,可能会缩短您的程序,同时使它更快一些。
您看,将读取数据与累加器组合的方式并不完美,因为它需要复制Accum值,因此readdata / 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.
我没有尝试过代码,可能无法编译,我只是试图展示基本的想法。
答案 1 :(得分:0)
所以这就是我想出来的。我稍微修改了readdata / 2以优化追加并删除换行符。 write / 2函数使用list: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"]
当然,如果你只是复制文件,德米特里的回答会更好。