1

我想创建一个唯一的目录来控制目录的磁盘配额。唯一的目录名称创建如下:

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 包含“/”,它会导致问题。

恐怕如果只是删除“/”,唯一的功能就会丢失。如何解决问题?另外,目录中是否还有其他字符不能使用?

4

5 回答 5

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 时间造成重大干扰),则该方法可以有效地工作。

于 2013-01-05T18:12:25.387 回答
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())))
于 2013-01-05T09:56:49.013 回答
0

Riak 使用来自 ref 和时间戳的 sha 哈希来生成唯一键。

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

于 2013-01-14T10:26:16.783 回答
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()))).
于 2013-01-11T14:37:59.327 回答
0

如果您只需要一个唯一值,并且每毫秒不需要超过 1 个,那么为什么不直接使用当前系统时间到毫秒呢?它比您上面提到的功能要快得多,并且非常独特。

如果有机会在一毫秒内获得超过一个,您可以将最后一个唯一值存储在静态变量中,并确保新的值大于它,否则使用最后一个值加一。

于 2013-01-05T10:05:56.750 回答