Ho bisogno di mettere i dati in un file poiché la mia altra funzione accetta un file come input.Come si crea un nome file temporaneo in Erlang?
Come si crea un nome file univoco in Erlang?
Esiste qualcosa come "tempfile" unix?
Ho bisogno di mettere i dati in un file poiché la mia altra funzione accetta un file come input.Come si crea un nome file temporaneo in Erlang?
Come si crea un nome file univoco in Erlang?
Esiste qualcosa come "tempfile" unix?
Significa solo generare il nome file acutale? In tal caso, il modo più sicuro sarebbe utilizzare un mix dei numeri che si ottengono da ora() e il nome host del computer (se si hanno diversi nodi che fanno la stessa cosa).
Qualcosa di simile:
1> {A,B,C}=now().
{1249,304278,322000}
2> N=node().
[email protected]
3> lists:flatten(io_lib:format("~p-~p.~p.~p",[N,A,B,C])).
"[email protected]"
4>
È inoltre possibile utilizzare TMP = lib:nonl(os:cmd("mktemp")).
Leggermente più brutto, ma 'string: strip (os: cmd (" mktemp "), a destra, $ \ n)' può evitare quella fastidiosa newline invisibile che di solito verrà restituita alla fine. – zxq9
Versione più breve: 'lib: nonl (os: cmd (" mktemp "))'. –
Mentre funziona, dipende dalla piattaforma. –
Oppure si potrebbe fare
erlang:phash2(make_ref())
per un identificatore unico semplice e veloce. Unico per un massimo di 2^82 chiamate che dovrebbero essere sufficienti per i tuoi scopi. Trovo questo più facile di formattazione di un timestamp con il nome del nodo per l'uso.
risposta tardiva: ho appena notato il modulo test_server che ha il sostegno di directory zero, vale la pena dare un'occhiata
Non garantisce che questo file non esisterà nel tempo in cui tenterai di creare questo file. Quindi non è sicuro. Ecco perché c'è 'mkstemp' in' stdlib.h'. 'mktemp' da GNU coreutils usa internamente la chiamata' mkstemp'. –
ho finalmente avuto questo problema - e il mio utente sta utilizzando un mix di Windows e Sistemi Linux, quindi il vecchio metodo collaudato lib:nonl(os:cmd("mktemp"))
non lo taglierà più.
Quindi ecco come l'ho affrontato, entrambi con una funzione mktemp/1
che restituisce un nome file che può essere utilizzato e anche 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 di 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 fondamentalmente la stessa cosa: si ottiene un nome fortemente casuale come un binario, convertire in una stringa base36, e aggiungerlo a qualsiasi il sistema operativo ci restituisce come posizione cache temporanea locale sicura dell'utente.
Su un sistema di tipo unix, ovviamente, potremmo semplicemente usare filename:join(["/tmp", Prefix, Rand])
ma l'indisponibilità di /tmp
su Windows è una specie di punto.
Poiché non tutti sono a conoscenza di ciò: chiamate a erlang: now() è garantito che restituiscono risultati univoci ogni volta. Abbastanza utile proprietà ... – viraptor
Sì, molto utile. C'è un'altra cosa che è molto utile con questo modo di generare un riferimento; si ottiene il nodename in là che è molto utile se si vuole prima assicurarsi che l'id sia sempre univoco (si può considerare come riferimento locale) e in secondo luogo sapere da dove proviene il riferimento. Nel nostro sistema (con n nodi nel cluster e dati condivisi, ecc.) Possiamo facilmente trovare i log e le informazioni di cui abbiamo bisogno su un lavoro usando questo identificatore solo (Nodo + Ora). –
Fallirà se tale file esiste già. erlang: now() non può garantire che il file non esista. –