Come faccio a creare un nome file temporaneo in Erlang?
Domanda
Devo inserire i dati in un file poiché la mia altra funzione accetta un file come input.
Come posso creare un nome file univoco in Erlang?
Fa qualcosa come unix " tempfile " esistere?
Soluzione
Intendi semplicemente generare il nome file acutal? In tal caso, il modo più sicuro sarebbe quello di utilizzare una combinazione dei numeri che ottieni da adesso () e il nome host del tuo computer (se hai diversi nodi che fanno la stessa cosa).
Qualcosa del tipo:
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>
Altri suggerimenti
Puoi anche usare TMP = lib: nonl (os: cmd (" mktemp ")).
O potresti farlo
Erlang: phash2 (make_ref ())
per un identificatore univoco rapido e semplice. Unico per un massimo di 2 ^ 82 chiamate che dovrebbe essere sufficiente per i tuoi scopi. Lo trovo più semplice della formattazione di un timestamp con il nome del nodo da utilizzare.
Risposta tardiva: ho appena notato il modulo test_server che ha il supporto della directory scratch, vale la pena dare un'occhiata
Finalmente ho avuto questo problema - e il mio utente sta usando un mix di sistemi Windows e Linux, quindi il vecchio provato e vero lib: nonl (os: cmd (" mktemp ")) Il metodo
non lo taglierà più.
Quindi ecco come l'ho affrontato, sia con una funzione mktemp / 1
che restituisce un nome file che può essere utilizzato, sia una funzione mktemp_dir / 1
che restituisce una directory (dopo averla creata).
-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 la versione della directory:
-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.
Entrambi fanno sostanzialmente la stessa cosa: otteniamo un nome fortemente casuale come binario, lo convertiamo in una stringa base36 e lo aggiungiamo a qualunque cosa il sistema operativo ci restituisca come posizione di cache temporanea sicura dell'utente-locale.
Su un sistema di tipo unix, ovviamente, potremmo semplicemente usare nomefile: join ([" / tmp " ;, Prefisso, Rand])
ma l'indisponibilità di / tmp
su Windows è una specie di punto qui.