Como faço para criar um nome de arquivo temporário em Erlang?
Pergunta
Eu preciso colocar dados em um arquivo desde a minha outra função recebe um arquivo como entrada.
Como faço para criar um nome de arquivo único em Erlang?
faz algo parecido unix existe "tempfile"?
Solução
Você quer dizer apenas gerar o nome do arquivo acutal? Nesse caso, a forma mais segura seria a utilização de uma mistura dos números que você começa a partir de agora () e o nome do host do seu computador (se você tiver vários nós fazendo a mesma coisa).
Algo como:
1> {A,B,C}=now().
{1249,304278,322000}
2> N=node().
nonode@nohost
3> lists:flatten(io_lib:format("~p-~p.~p.~p",[N,A,B,C])).
"nonode@nohost-1249.304278.322000"
4>
Outras dicas
Você também pode usar TMP = lib:nonl(os:cmd("mktemp")).
Ou você poderia fazer
erlang:phash2(make_ref())
para um identificador da única rápido e fácil. Única para até 2 ^ 82 chamadas que deve ser enough.for seus propósitos. Acho isso mais fácil do que a formatação de um timestamp com o nome do nó para o uso.
resposta tardia: Eu só notei o módulo test_server que tem apoio diretório do zero, vale uma olhada
Eu finalmente tive esse problema -. E meu usuário é usando uma mistura de sistemas Windows e Linux, então o velho tentou-e true-método lib:nonl(os:cmd("mktemp"))
só não vai cortá-la mais
Então aqui está como eu aproximou-se, ambos com uma função mktemp/1
que retorna um nome de arquivo que pode ser usado e também uma função mktemp_dir/1
que retorna um diretório (depois de ter criado-lo).
-spec mktemp(Prefix) -> Result
when Prefix :: string(),
Result :: {ok, TempFile :: file:filename()}
| {error, Reason :: file:posix()}.
mktemp(Prefix) ->
Rand = integer_to_list(binary:decode_unsigned(crypto:strong_rand_bytes(8)), 36),
TempPath = filename:basedir(user_cache, Prefix),
TempFile = filename:join(TempPath, Rand),
Result1 = file:ensure_dir(TempFile),
Result2 = file:write_file(TempFile, <<>>),
case {Result1, Result2} of
{ok, ok} -> {ok, TempFile};
{ok, Error} -> Error;
{Error, _} -> Error
end.
E a versão diretório:
-spec mktemp_dir(Prefix) -> Result
when Prefix :: string(),
Result :: {ok, TempDir :: file:filename()}
| {error, Reason :: file:posix()}.
mktemp_dir(Prefix) ->
Rand = integer_to_list(binary:decode_unsigned(crypto:strong_rand_bytes(8)), 36),
TempPath = filename:basedir(user_cache, Prefix),
TempDir = filename:join(TempPath, Rand),
Result1 = file:ensure_dir(TempDir),
Result2 = file:make_dir(TempDir),
case {Result1, Result2} of
{ok, ok} -> {ok, TempDir};
{ok, Error} -> Error;
{Error, _} -> Error
end.
Ambos fazem basicamente a mesma coisa: temos um nome fortemente aleatório como um binário, convertê-lo em uma string base36, e anexá-lo a qualquer que seja o sistema operacional retorna para nós como um local de cache temporário local pelo usuário segura <. / p>
Em um sistema tipo Unix, é claro, que poderia usar apenas filename:join(["/tmp", Prefix, Rand])
mas a indisponibilidade de /tmp
no Windows é uma espécie de todo o ponto aqui.