保存元组到磁盘

        ETS表把元组保存在内存里,而DETS提供了把Erlang元组保存到磁盘上的方法。DETS的最 大文件大小是2GB。DETS文件必须先打开才能使用,用完后还应该正确关闭。如果没有正确关 闭,它们就会在下次打开时自动进行修复。因为修复可能会花很长一段时间,所以先正确关闭它 们再结束程序是很重要的。 DETS表有着和ETS表不同的共享属性。DETS表在打开时必须赋予一个全局名称。如果两个 或更多本地进程用相同的名称和选项打开某个DETS表,它们就会共享这个表。这个表会一直处于打开状态,直到所有进程都关闭它(或者崩溃)。

        接下来我们将创建一个基于磁盘的表,它将把文件名映射到整数上,反之亦然。我们将定义函数 filename2index和它的逆函数index2filename。 为了实现这个索引,我们将创建一个DETS表,然后用三种不同类型的元组填充它。

{free, N}

       N是表里的第一个空白索引。当我们在表里输入一个新文件名时,就会指派索引N给它。

{FileNameBin, K}

        FileNameBin(一个二进制型)被指派了索引K。

{K, FileNameBin}

        K(一个整数)代表文件FilenameBin。

        请注意,每个新添加的文件都会在表里增加两个条目:一个File → Index条目和一个逆向 的Index → Filename条目。这是出于效率的原因。当ETS或DETS表建立时,元组里只有一个元素充当键的角色。匹配某个非键元组元素虽然可行,但非常低效,因为它涉及对整个表进行搜索。当整个表都在磁盘上时,这个操作的代价尤其高昂。

        现在来编写这个程序。首先编写打开和关闭DETS表的函数,这个表用来保存所有的文件名。

open(File) ->
  io:format ("detsopened:~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。

        打开文件之后,向表里插入一个新文件名就很简单了。它是由filename2index调用产生的副作用实现的。如果文件名在表里,就会返回它的索引,否则就会生成一个新索引并更新表,而 这次更新会使用三个元组。

filename2index(FileName) when is_binary(FileName) ->
  case dets:lookup(?MODULE, FileName) of
    [] ->
      [{_, Free}] = dets:lookup(?MODULE, free),
      ok = dets:insert(?MODULE, [{Free, FileName}, {FileName, Free}, {free, Free+1}]),
      Free;
    [{_, N}] ->
      N
  end.

         把索引转换成文件名非常简单。

index2filename(Index) when is_integer(Index) ->
  case dets:lookup(?MODULE, Index) of
    []           -> error;
    [{_, Bin}]   -> Bin
  end.

        我们测试一下

        发现创建了应该file文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值