1

我问了一个类似的问题,不知道有什么不清楚的,但我会再试一次。我有一个文件。文件名是 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 行..等等.. 一样:)

4

2 回答 2

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.

我没有尝试过代码,它可能无法编译,我只是试图展示基本思想。

于 2013-01-22T20:19:04.250 回答
0

所以这就是我想出的。我稍微修改了您的 readdata/2 以优化附加并删除换行符。write/2 函数使用 lists: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"]

当然,如果您只是复制文件,Dmitry 的答案会更好。

于 2013-01-22T22:32:57.323 回答