9
votes

Comment créer un nom de fichier temporaire à Erlang?

J'ai besoin de mettre des données dans un fichier car mon autre fonction prend un fichier comme entrée.

Comment créer un nom de fichier unique à Erlang?

fait quelque chose comme unix "tempfile" exister?


0 commentaires

6 Réponses :


12
votes

Voulez-vous simplement générer le nom de fichier acutal? Dans ce cas, la manière la plus sûre serait d'utiliser un mélange de chiffres que vous obtenez d'ici () et du nom d'hôte de votre ordinateur (si vous avez plusieurs nœuds qui font la même chose).

Quelque chose comme: < Pré> xxx


5 commentaires

Comme tout le monde n'est pas conscient de cela: des appels à Erlang: maintenant () sont garantis pour renvoyer des résultats uniques à chaque fois. Propriété assez utile ...


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 la nodename là-bas qui est très utile si vous souhaitez d'abord vous assurer que l'ID est toujours unique (vous pouvez le traiter comme une référence locale) et une seconde à savoir d'où provient la référence. Dans notre système (avec n nœuds dans le cluster et les datables partagés, etc.), nous pouvons facilement trouver les journaux et informations dont nous avons besoin sur un travail utilisant cet identifiant uniquement (nœud + heure).


Cela échouera si un tel fichier existe déjà. Erlang: Maintenant () Impossible de garantir que le fichier n'existe pas.


Erlang: maintenant / 0 est obsolète, utilisez erlang: unique_integer / 0 ( docs ) à la place.


Cela a la faiblesse qu'il ne protège pas contre une collision de nom entre deux processus concurrents. Il est possible que deux processus génèrent le nom de fichier au même microseconde. Je traite actuellement une insuffisance de construction intermittente due à l'utilisation d'un outil de construction de ce nom TMPFile basé sur l'horodatage. Utilisez la solution MKTemp à la place.



10
votes

Vous pouvez également utiliser TMP = lib: nonL (OS: cmd ("mktemp")).


2 commentaires

Légèrement plus laidule, mais String: Strip (OS: CMD ("MKTemp"), Droite, $ \ N) peut éviter que cette nouvelle ligne invisible ne soit généralement renvoyée à la fin.


Version plus courte: in: non (OS: commande ("mktemp")) .



7
votes

ou vous pouvez faire

erlang: phash2 (make_ref ())

pour un indentificateur unique rapide et facile. Unique pour des appels allant jusqu'à 2 ^ 82 qui devrait suffire. Pour vos besoins. Je trouve cela plus facile que le formatage d'un horodatage avec nom de nœud à utiliser.


0 commentaires

1
votes

Réponse tardive: Je viens de remarquer le module Test_Server qui possède un support de répertoire de gratter, vaut la peine de regarder

http://www.erlang.org/doc/man /Test_Server.html#temp_name-1


1 commentaires

Cela ne garantit pas que ce fichier n'existera pas dans le temps que vous allez essayer de faire ce fichier. Donc, ce n'est pas sécurisé. C'est pourquoi il y a mkystemp dans stdlib.h . mktemp de gnu cortitils utilise mkstemp appel interne.



1
votes

J'ai enfin eu ce problème - et mon utilisateur utilise un mélange de systèmes Windows et Linux, de sorte que l'ancien eye-and-true lib: nonL (OS: cmd ("mktemp")) / Code> La méthode ne va tout simplement pas le couper.

Voici comment je m'approche, avec une fonction mktemp / 1 code> qui renvoie un nom de fichier qui peut être utilisé et aussi une fonction mktemp_dir / 1 code> qui renvoie un répertoire (après l'avoir créée). p> xxx pré>

et la version répertoire: p>

-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 = filelib:ensure_dir(TempDir),
    Result2 = file:make_dir(TempDir),
    case {Result1, Result2} of
         {ok, ok}    -> {ok, TempDir};
         {ok, Error} -> Error;
         {Error, _}  -> Error
    end.



0
votes

dans OTP 24 Il n'y a pas Fichier: S'assurer_dir . Donc, j'ai fait quelque chose de similaire:

pour le répertoire: xxx

pour fichier: xxx


0 commentaires