Проблемы с чтением файла в erlang - PullRequest
0 голосов
/ 24 июня 2018

Итак, я пытаюсь читать и записывать в файл.При записи в файл мне нужно проверить, существует ли определенный индекс в файле, тогда я не пишу и выкидываю ошибку.Данные в файле будут выглядеть так:

{1,{data,dcA,1}}.
{2, {data, dcA, 2}}.
{3,{data,dcA,3}}.

Я добавил точку в конце каждой строки, потому что file: consult () нуждается в таком файле.

В этом формате.

{Index, {Data, Node, Index}}

Когда мне нужно добавить новый файл, я проверяю этот индекс.

Вот что я пробовал до сих пор - https://pastebin.com/apnWLk45

И я запускаю это так:

193> {ok, P9} = poc:start(test1, self()).
{ok,<0.2863.0>}
194> poc:add(P9, Node, {6, data}).

В POC: добавить / 3, P9 - процессидентификатор из файла: открыть.Ранее я определил в оболочке как dcA. И третье - это данные - которые находятся в этом формате - {Index, data}

Поскольку я использую файл: consult / 1, он принимает имя файла в качестве параметра.На данный момент у меня есть только идентификатор процесса.Поэтому я беру имя из file:pid2name(_Server).

. Это отлично работает, когда я запускаю его впервые.

Когда я запускаю это снова - poc: add (P9, Node, {6, data2}), я получаю сообщение об ошибке в этой строке file:pid2name(_Server).

exception error: no match of right hand side value undefined

Как мне решить эту проблему?

Я новичок в Erlang.Просто была неделя, которую я начал изучать.

1 Ответ

0 голосов
/ 24 июня 2018

Я пытаюсь прочитать и записать в файл.При записи в файл мне нужно проверить, существует ли определенный индекс в файле, тогда я не пишу и выкидываю ошибку.

Таблица DETS может легко сделать то, что вы хотите:

-module(my).
-compile(export_all).

open_table() ->
    dets:open_file(my_data, [{type, set}, {file, "./my_data.dets"}]).

close_table() ->
    dets:close(my_data).

clear_table() ->
    dets:delete_all_objects(my_data).

insert({Key, _Rest}=Data) ->
    case dets:member(my_data, Key) of 
        true    -> throw(index_already_exists);
        false   -> dets:insert(my_data, Data)
    end.

all_items() ->
    dets:match(my_data, '$1').

В оболочке:

~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V9.2  (abort with ^G)

1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}

2> my:open_table().
{ok,my_data}

3> my:clear_table().
ok

4> my:all_items().
[]

5> my:insert({1, {data, a, b}}).
ok

6> my:insert({2, {data, c, d}}).
ok

7> my:insert({3, {data, e, f}}).
ok

8> my:all_items(). 
[[{1,{data,a,b}}],[{2,{data,c,d}}],[{3,{data,e,f}}]]

9> my:insert({1, {data, e, f}}).
** exception throw: index_already_exists
    in function  my:insert/1 (my.erl, line 15)

При повторном запуске - poc: add (P9, Node, {6, data2}), я получаю сообщение об ошибке в этом файле строки: pid2name (_Server):

exception error: no match of right hand side value undefined

Когда процесс открывает файл, он становится связанным с процессом, который обрабатывает файловый ввод-выводЭто означает, что если процесс, открывающий файл, завершается ненормально, процесс ввода-вывода также завершается.Вот пример:

-module(my).
-compile(export_all).

start() ->
    {ok, Pid} = file:open('data.txt', [read, write]),
    spawn(my, add, [Pid, x, y]),
    exit("bye").


add(Pid, _X, _Y) ->
    timer:sleep(1000),  %Let start() process terminate.
    {ok, Fname} = file:pid2name(Pid),
    io:format("~s~n", [Fname]).

В оболочке:

1> c(my).     
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}

2> my:start().
** exception exit: "bye"
     in function  my:start/0 (my.erl, line 7)
3> 
=ERROR REPORT==== 25-Jun-2018::13:28:48 ===
Error in process <0.72.0> with exit value:
{{badmatch,undefined},[{my,add,3,[{file,"my.erl"},{line,12}]}]}

В соответствии с pid2name () docs :

pid2name(Pid) -> {ok, Filename} | undefined

функция может возвращать undefined, как сообщается в сообщении об ошибке.

...