Как мне создать временное имя файла в Erlang? - PullRequest
8 голосов
/ 03 августа 2009

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

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

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

Ответы [ 5 ]

12 голосов
/ 03 августа 2009

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

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

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> 
9 голосов
/ 03 августа 2009

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

6 голосов
/ 06 августа 2009

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

erlang:phash2(make_ref())

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

1 голос
/ 06 сентября 2009

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

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

0 голосов
/ 12 августа 2017

У меня наконец-то возникла эта проблема - и мой пользователь использует сочетание систем 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 - вот в чем вся суть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...