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に「/」が含まれているため、問題が発生しました。

「/」を削除するだけでは、uniqueの機能が失われるのではないかと思います。問題を解決する方法は?また、ディレクトリで使用できない他の文字はありますか?

4

5 に答える 5

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 に答える
1

1つのerlangVMは、リクエストごとに異なる値を与えることを保証します。通常1msの精度で時間を与えるWindowsマシンでも、複数のアクセスで1µsの結果が得られます。

2> R = {now(),now(),now(),now()}.
{{1357,408695,109000},
 {1357,408695,109001},
 {1357,408695,109002},
 {1357,408695,109003}}

したがって、呼び出しの頻度が実際には1秒あたり1 000 000呼び出し未満であると考える場合(erlang時間の大きな混乱を回避することが重要です)、この方法は効率的に機能します。

于 2013-01-05T18:12:25.387 に答える
0

必要なのが一意の値だけで、1ミリ秒あたり1を超える必要がない場合は、現在のシステム時間をミリ秒単位で使用してみませんか?上記の機能よりもはるかに高速で、適切にユニークです。

1ミリ秒に複数の値を取得する可能性がある場合は、最後の一意の値を静的変数に格納し、新しい値がそれよりも大きいことを確認します。それ以外の場合は、最後の値に1を加えた値を使用します。

于 2013-01-05T10:05:56.750 に答える
0

ref()を文字列として使用して、VMを再起動すると、同じディレクトリ名を取得できます。それは重要ですか?他のユーザーが言うように、呼び出しの頻度がマイクロ秒あたり1呼び出し未満の場合は、now()を使用できます。

2つの推測

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

Riakは、refとtimestampからの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 に答える