2013-01-05 40 views
0

我想爲控制目錄的磁盤配額創建唯一的目錄。獨特的目錄名稱創建如下:目錄的唯一字符串

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包含 「/」,它引起的問題。

我怕只要刪除「/」,唯一的特徵就會丟失。如何解決問題? 另外,還有其他的字符不能在目錄中使用嗎?

+3

在文件名中不允許的字符每個操作系統而有所不同。你確定你不想要[UUID](http://stackoverflow.com/questions/1657204/erlang-uuid-generator)嗎? –

+0

非常感謝您的回覆。 UUID可以滿足我的要求。 –

回答

1

您可以用hexify函數替換base64:encode_to_string函數,如下所示。

hexify(Binary) -> 
    lists:flatten([io_lib:format("~2.16.0b", [B]) || <<B>> <= Binary]). 

您還可以調整此功能以允許使用不同的字符集。

順便說一句,我建議做一些散列在裁判名稱相同的長度。

hexify(crypto:md5(term_to_binary(make_ref()))) 
+0

這也是一個好主意。 –

+0

cryto:md5沒有必要,它已經是相同的長度。 –

0

如果你需要的是一個獨特的價值,你並不需要超過1每毫秒,爲什麼不直接使用當前系統時間到毫秒?它比上面提到的功能要快得多,並且適合獨特。

如果有可能在一毫秒內獲得多個值,那麼可以將最後一個唯一值存儲在一個靜態變量中,並確保新值大於它,否則使用最後一個值加一。

+2

由於許多進程在同一時間運行,因此可能會發生衝突。 –

+0

一個erlang VM保證爲每個時間請求提供不同的值。即使在Windows機器上,通常以1ms精度給出時間,多次訪問也會在1μs時產生結果: – Pascal

1

一個erlang VM保證爲每個時間請求提供不同的值。即使是在Windows機器通常給的時間爲1毫秒的精度上,多次訪問給在1μs的結果:

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

所以,如果你認爲通話的頻率是每秒真小於1個000 000電話(它對於避免Erlang時間的重大幹擾非常重要),該方法可以有效地工作。

+0

使用此方法存在危險:反覆使用erlang:now()會迅速導致時鐘偏斜。 http://erlang.org/doc/man/erlang.html#now-0 – macintux

+0

你是對的,這就是爲什麼只有在平均通話頻率有限的情況下才能使用它。 – Pascal

0

將ref()作爲字符串使用,如果重新啓動VM,則可以獲得相同的目錄名稱。這很重要嗎? 正如其他用戶所說,如果每微秒呼叫頻率小於1個呼叫,則可以使用now()。

兩個sugestions

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()))).