2009-08-03 19 views

Respuesta

12

¿Quiere decir simplemente generar el nombre de archivo acutal? En ese caso, la forma más segura sería usar una combinación de los números que obtiene 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(). 
[email protected] 
3> lists:flatten(io_lib:format("~p-~p.~p.~p",[N,A,B,C])). 
"[email protected]" 
4> 
+4

Dado que no todo el mundo es consciente de eso, las llamadas a erlang: now() están garantizadas para devolver resultados únicos cada vez. Propiedad muy útil ... – viraptor

+0

Sí, muy útil. Hay otra cosa que es muy útil con esta forma de generar una referencia; obtienes el nombre del nodo que es muy útil si primero quieres asegurarte de que el ID sea único (puedes tratarlo como una referencia local) y segundo para saber de dónde viene la referencia. En nuestro sistema (con n nodos en el clúster y tablas de datos compartidos, etc.) podemos encontrar fácilmente los registros y la información que necesitamos sobre un trabajo utilizando solo este identificador (Nodo + Tiempo). –

+0

Fallará si dicho archivo ya existe. erlang: now() no puede garantizar que el archivo no exista. –

9

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

+2

Un poco más feo, pero 'string: strip (os: cmd (" mktemp "), right, $ \ n)' puede evitar esa nueva línea invisible molesta que generalmente se devolverá al final. – zxq9

+1

Versión más corta: 'lib: nonl (os: cmd (" mktemp "))'. –

+0

Mientras esto funciona, depende de la plataforma. –

6

O usted podría hacer

erlang:phash2(make_ref())

para una rápida y fácil indentifier único. Único para hasta 2^82 llamadas que deberían ser suficientes. Para sus propósitos. Me resulta más fácil que formatear una marca de tiempo con nombre de nodo para su uso.

1

respuesta tardía: Acabo de notar el módulo test_server que cuenta con el apoyo del directorio de cero, vale la pena un vistazo

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

+0

No garantiza que este archivo no exista a tiempo. Intentarás crear este archivo. Entonces no es seguro. Es por eso que hay 'mkstemp' en' stdlib.h'. 'mktemp' de GNU coreutils usa la llamada' mkstemp' internamente. –

0

fin he tenido este problema - y mi usuario está utilizando una mezcla de Windows y Sistemas Linux, por lo que el viejo y probado método lib:nonl(os:cmd("mktemp")) ya no lo va a cortar.

Así que aquí es cómo me he acercado a ella, ambos con una función mktemp/1 que devuelve un nombre de archivo que se puede utilizar y también una función que devuelve mktemp_dir/1 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 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: tenemos un nombre fuertemente al azar como un binario, convertir eso en una cadena base36, y añadirlo a lo el sistema operativo regresa a nosotros como una ubicación de caché temporal local segura para el usuario.

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

Cuestiones relacionadas