使用Erlang进行I / O,尝试将输入文件放入列表中

时间:2015-10-27 00:12:45

标签: erlang

-module(test).
-export([run/1]).

open_file(FileName, Mode) ->
    {ok, Device} = file:open(FileName, [Mode, binary]),    Device.

close_file(Device) ->
    ok = file:close(Device).

read(File) ->
    case file:read_line(File) of
        {ok, Data} -> [Data | read(File)];
        eof        -> []
    end.
run(InputFileName) ->
    Device = open_file(InputFileName, read),
    Data = read(Device),
    [First |TheRest] = Data,
    io:format("First line is ~p ~n", [First]),
    close_file(Device).

原始文件

d1  and is  program program the
d2  a   apply   copyleft    free    free    freedom
d3  copyleft    copyleft    share   share   users
d4  released    software    works
d5  licenses    licenses    licenses    licenses    licenses    software
d8  apply

以某种方式变成

50> test:run("input.txt").
First line is <<"d1\tand\tis\tprogram\tprogram\tthe\n">> 
ok

这是表示列表的特殊方式吗?或者我是否需要使用某种模块将读取转换为列表?

我的最终目标是使用列表创建密钥对:

{d1 [and is program program the]}

谢谢!

1 个答案:

答案 0 :(得分:1)

您从文件中读取的数据表示为二进制文件,而不是字符串,因为您在打开文件时指定binary模式:

{ok, Device} = file:open(FileName, [Mode, binary]), Device.

如果您将其更改为:

{ok, Device} = file:open(FileName, [Mode]), Device.

你的结果变成了:

  

第一行是&#34; d1,是程序程序\ n&#34;

要获得最终结果,请将read/1功能更改为:

read(File) ->
    case file:read_line(File) of
        {ok, Data} ->
            [First|Rest] = string:tokens(Data, " \t\n"),
            [{First,string:join(Rest, "\t")} | read(File)];
        eof -> []
    end.

通过此更改,您的程序将打印:

  

第一行是{&#34; d1&#34;,&#34;和\ tis \ tprogram \ tprogram \ tthe&#34;}

其中第二个元素是一个字符串,其中标记与原始数据中的标签分隔。如果您希望第一个元素"d1"改为原子d1(我无法从您的问题中确定这是否是您想要的),您可以将其转换为{ {1}}。