J'ai enfin eu ce problème - et mon utilisateur utilise un mélange de Windows et Systèmes Linux, donc la vieille méthode éprouvée lib:nonl(os:cmd("mktemp"))
ne va tout simplement plus la couper.
Voici donc comment je l'ai abordé, à la fois avec une fonction mktemp/1
qui retourne un nom de fichier qui peut être utilisé et aussi une fonction mktemp_dir/1
qui retourne un répertoire (après l'avoir créé).
-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.
Et la version du répertoire:
-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.
Ces deux font essentiellement la même chose: nous obtenons un nom fortement aléatoire comme binaire, convertir en une chaîne de base36, et l'ajouter à tout le système d'exploitation nous revient en tant qu'emplacement de cache temporaire local-utilisateur sécurisé.
Sur un système de type Unix, bien sûr, nous pourrions simplement utiliser filename:join(["/tmp", Prefix, Rand])
mais l'indisponibilité de /tmp
sur Windows est en quelque sorte le point entier ici.
Comme tout le monde ne le sait pas: les appels à erlang: now() garantissent des résultats uniques à chaque fois. Propriété assez utile ... – viraptor
Oui, très utile. Il y a une autre chose qui est très utile avec cette façon de générer une référence; vous obtenez le nom de noeud qui est très utile si vous voulez d'abord vous assurer que l'identifiant est toujours unique (vous pouvez le traiter comme une référence locale) et le second pour savoir d'où vient la référence. Dans notre système (avec n nœuds dans le cluster et les données partagées, etc.), nous pouvons facilement trouver les journaux et les informations dont nous avons besoin à propos d'un travail en utilisant cet identifiant seulement (Node + Time). –
Il échouera si un tel fichier existe déjà. erlang: now() ne peut pas garantir que le fichier n'existe pas. –