Как мне создать временное имя файла в Erlang?
Вопрос
Мне нужно поместить данные в файл, так как моя другая функция принимает файл в качестве входных данных.
Как мне создать уникальное имя файла в 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 - вот в чем вся суть.