ERLANG学习 Day14

保存元组到磁盘

        ETS表把元组保存在内存里,而DETS提供了把Erlang元组保存到磁盘上的方法。DETS的最 大文件大小是2GB。DETS文件必须先打开才能使用,用完后还应该正确关闭。如果没有正确关 闭,它们就会在下次打开时自动进行修复。

        DETS表有着和ETS表不同的共享属性。DETS表在打开时需要设置一个全局名称。如果两个 或更多本地进程用相同的名称和选项打开某个DETS表,它们就会共享这个表。这个表会一直处 于打开状态,直到所有进程都关闭它(或者崩溃)。

-module(lib_filenames_dets).
-author("chen").

%% API
-export([open/1, close/0).
open(File) ->
  io:format("dets opened;~p~n", [File]),
  Bool = filelib:is_file(File),
  case dets:open_file(?MODULE, [{file, File}]) of
    {ok, ?MODULE} ->
      case Bool of
        true -> void;
        false -> ok = dets:insert(?MODULE, {free, 1})
      end,
      true;
    {error, Reason} -> io:format("cannot open dets table~n"),
      exit({eDetsOpen, File, Reason})
  end.
close() -> dets:close(?MODULE).

 

        open的代码会自动初始化DETS表,方法是在创建新表时插入{free, 1}元组。如果File存 在,filelib:is_file(File)就会返回true,否则返回false。请注意,dets:open_file或者 创建一个新文件,或者打开一个现有文件,调用dets:open_file前先检查文件是否存在的原因。

 在进程中实现

-module(dets_example).
-author("chen").

%% API

-export([start/0, stop/0, write/2,  init/0, read/1]).

start() ->
  register(dets_server, spawn(fun() -> init() end)).

stop() ->
  dets_server ! stop.

write(K, V) ->
  dets_server ! {write, {K, V}}.

read(K) ->
  dets_server ! {read, K}.

init() ->
  {ok,DetS}=dets:open_file(tableName,[{file,"file1.det"}]),
  loop(DetS).

loop(DetS)->
  receive
    {write, {K, V}}->
      Reply=dets:insert(DetS, {K, V}),
      io:format("~p~n", [Reply]),
      loop(DetS);
    stop->
      ok;
    {read, Key}->
      case dets:lookup(DetS, Key) of
        [{K, V}] when K == Key ->
          io:format("the value is~p~n", [V]),
          loop(DetS);
        [] ->
          io:format("Not found~n", []),
          loop(DetS);
        Error ->
          io:format("Error: ~p~n", [Error]),
          loop(DetS)
      end;
    _ ->
      io:format("Unknown message~n", []),
      loop(DetS)
  end.

         在这个代码中,我们使用 spawn 函数创建了一个名为 dets_server 的进程,并将其注册为 dets_server。该进程使用 loop/1 函数不断接收消息并处理它们。在 loop/1 函数中,我们使用 dets:open_file/1 打开一个名为 "file1.det" 的文件,当收到 write 消息时,会向表中添加一个新的键-值对。当收到 stop 消息时,我们退出循环并终止进程。当收到 read 消息时,我们使用 dets:lookup/2 在数据库中查找对应Key的值,并打印输出。当收到其他未知消息时,我们打印出一条未知消息的提示信息,并继续循环。

start() ->
  register(dets_server, spawn(fun() -> init() end)).
init() ->
  {ok,DetS}=dets:open_file(tableName,[{file,"file1.det"}]),
  loop(DetS).

启动进程,会调用初始化会创建或打开一个的文件。

write(K, V) ->
  dets_server ! {write, {K, V}}.

向表中添加一个新的键-值对

read(K) -> dets_server ! {read, K}.

向dets_server 进程发送{read, K},会使用 dets:lookup/2 在表查找对应Key的值,

stop() ->
  dets_server ! stop.

停止进程。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值