我想创建唯一的目录来控制目录的磁盘配额。唯一目录名称创建如下:
unique_string()->
base64:encode_to_string(term_to_binary(make_ref())).
但是当调试时,问题出现了:
exception exit: {{badmatch,
{error,
" g3IAA2QAFGVtYWNzQHl1cy1pTWFjLmxvY2FsAwAB/ncAAAA8AAAAAA==: No such file or directory.\r\n"}},
unique_string包含“/”,它引起了问题。
我担心如果只删除“/”,唯一的功能就会丢失。如何解决问题? 另外,目录中是否还有其他字符不能使用?
答案 0 :(得分:1)
您可以使用base64:encode_to_string
函数替换hexify
,如下所示。
hexify(Binary) ->
lists:flatten([io_lib:format("~2.16.0b", [B]) || <<B>> <= Binary]).
您也可以调整此功能以允许使用不同的字符集。
顺便说一下,我建议在ref上做一些散列,使名字长度相同。hexify(crypto:md5(term_to_binary(make_ref())))
答案 1 :(得分:1)
一个erlang VM保证为每个时间请求提供不同的值。即使在通常以1 ms精度提供时间的Windows机器上,多次访问也会产生1μs的结果:
2> R = {now(),now(),now(),now()}.
{{1357,408695,109000},
{1357,408695,109001},
{1357,408695,109002},
{1357,408695,109003}}
因此,如果您认为呼叫频率确实低于每秒1 000 000次呼叫(避免对erlang时间造成严重干扰很重要),该方法可以高效工作。
答案 2 :(得分:0)
如果您只需要一个唯一值,并且每毫秒不需要超过1,那么为什么不将当前系统时间用于毫秒?它比上面提到的功能快得多,而且非常独特。
如果有可能在一毫秒内获得多个,您可以将最后一个唯一值存储在静态变量中,并确保新值大于它,否则使用最后一个值加一。
答案 3 :(得分:0)
使用ref()作为字符串,如果重新启动VM,则可以获得相同的目录名称。这有关系吗? 正如其他用户所说,如果呼叫频率小于每微秒1次呼叫,你可以使用now()。
两次消化
random_md5_name() ->
Str = lists:flatten(io_lib:format("~p", [now()])),
lists:flatten([io_lib:format("~2.16.0b", [B]) || <<B>> <= erlang:md5(Str)].
random_numeric_name() ->
lists:flatten(io_lib:format("~p~p~p", tuple_to_list(now()))).
答案 4 :(得分:0)
Riak使用ref和timestamp中的sha hash生成唯一键。
crypto:sha(term_to_binary({make_ref(), os:timestamp()}))
https://github.com/basho/riak_core/blob/1.2.1p1/src/riak_core_util.erl#L135