Как мне создать временное имя файла в Erlang?

StackOverflow https://stackoverflow.com/questions/1222084

  •  10-07-2019
  •  | 
  •  

Вопрос

Мне нужно поместить данные в файл, так как моя другая функция принимает файл в качестве входных данных.

Как мне создать уникальное имя файла в Erlang?

Существует ли что-то вроде unix "tempfile"?

Это было полезно?

Решение

Вы имеете в виду просто создать точное имя файла? В этом случае самым безопасным способом было бы использовать сочетание чисел, которые вы получаете сейчас (), и имени хоста вашего компьютера (если у вас есть несколько узлов, делающих одно и то же).

Что-то вроде:

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> 

Другие советы

Вы также можете использовать TMP = lib: nonl (os: cmd (" mktemp ")).

Или вы могли бы сделать

erlang:phash2(make_ref())

для быстрого и легкого создания уникального идентификатора.Уникальный для 2 ^ 82 вызовов, чего должно быть достаточно.для ваших целей.Я нахожу это проще, чем форматировать временную метку с именем узла для использования.

Поздний ответ: я только что обратил внимание на модуль test_server, в котором есть поддержка чистых каталогов, на который стоит обратить внимание

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

У меня наконец-то возникла эта проблема - и мой пользователь использует смесь систем Windows и Linux, поэтому старый проверенный lib: nonl (os: cmd (" mktemp ")) Метод больше не собирается его сокращать.

Итак, вот как я подошел к этому, как с функцией mktemp / 1 , которая возвращает имя файла, которое можно использовать, так и с функцией mktemp_dir / 1 , которая возвращает каталог (после его создания).

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

И версия каталога:

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

Оба они в основном делают одно и то же: мы получаем строго случайное имя в виде двоичного файла, преобразуем его в строку base36 и добавляем его к тому, что операционная система возвращает нам в качестве безопасного места временного кэша пользователя.

В системе типов Unix, конечно, мы могли бы просто использовать filename: join ([" / tmp " ;, Prefix, Rand]) , но недоступность / tmp в Windows - вот в чем вся суть.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top