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 に答える