Pregunta

Necesito poner datos en un archivo ya que mi otra función toma un archivo como entrada.

¿Cómo creo un nombre de archivo único en Erlang?

Hace algo así como unix "tempfile" existe?

¿Fue útil?

Solución

¿Quiere decir simplemente generar el nombre de archivo acutal? En ese caso, la forma más segura sería utilizar una combinación de los números que obtiene a partir de ahora () y el nombre de host de su computadora (si tiene varios nodos haciendo lo mismo).

Algo así 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> 

Otros consejos

También puede usar TMP = lib: nonl (os: cmd (" mktemp ")).

O podrías hacer

erlang:phash2(make_ref())

para un identificador único rápido y fácil. Único para hasta 2 ^ 82 llamadas, lo que debería ser suficiente para sus propósitos. Esto me resulta más fácil que formatear una marca de tiempo con el nombre del nodo para su uso.

Respuesta tardía: acabo de notar el módulo test_server que tiene soporte de directorio temporal, vale la pena echarle un vistazo

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

Finalmente tuve este problema, y ??mi usuario está usando una combinación de sistemas Windows y Linux, por lo que el viejo y probado lib: nonl (os: cmd (" mktemp ")) el método ya no lo va a cortar más.

Entonces, así es como lo he abordado, tanto con una función mktemp / 1 que devuelve un nombre de archivo que se puede usar como también una función mktemp_dir / 1 que devuelve un directorio (después de haberlo creado).

-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.

Y la versión del directorio:

-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 hacen básicamente lo mismo: obtenemos un nombre fuertemente aleatorio como binario, lo convertimos en una cadena base36 y lo agregamos a lo que el sistema operativo nos devuelve como una ubicación de caché temporal local segura para el usuario.

En un sistema de tipo unix, por supuesto, podríamos usar filename: join ([" / tmp " ;, Prefix, Rand]) pero la falta de disponibilidad de / tmp en Windows es una especie de punto completo aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top