保存元组到磁盘
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.
停止进程。