如何在Erlang中创建临时文件名?

时间:2009-08-03 12:30:09

标签: erlang filenames

我需要将数据放入文件中,因为我的其他函数将文件作为输入。

如何在Erlang中创建唯一的文件名?

是否存在类似unix“tempfile”的内容?

6 个答案:

答案 0 :(得分:12)

你的意思是只生成真实的文件名吗?在这种情况下,最安全的方法是使用从现在开始的数字()和计算机主机名的混合(如果你有几个节点做同样的事情)。

类似的东西:

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> 

答案 1 :(得分:9)

您也可以使用TMP = lib:nonl(os:cmd("mktemp")).

答案 2 :(得分:6)

或者你可以做到

erlang:phash2(make_ref())

快速简便的独特标识符。最多2 ^ 82个电话的独特之处,应该足够用于您的目的。我发现这比使用节点名称格式化时间戳更容易。

答案 3 :(得分:1)

迟到的回答:我刚刚注意到test_server模块,它具有临时目录支持,值得一看

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

答案 4 :(得分:0)

我终于遇到了这个问题 - 我的用户正在混合使用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字符串,并将其附加到操作系统作为安全的用户本地临时缓存位置返回给我们的任何内容。 / p>

在unix类型系统上,我们当然可以使用filename:join(["/tmp", Prefix, Rand]),但Windows上/tmp的不可用性就是这里的重点。

答案 5 :(得分:0)

在 OTP 24 中没有 file:ensure_dir。所以我做了类似的事情:

对于目录:

mktemp_dir(Prefix) ->
    Rand = integer_to_list(binary:decode_unsigned(crypto:strong_rand_bytes(8)), 36),
    TempDir = filename:basedir(user_cache, Prefix),
    []= os:cmd("mkdir " ++ "\"" ++ TempDir ++ "\""),
    {ok, _} = file:list_dir(TempDir),
    TempDir.

对于文件:

mktemp(Prefix) ->
    Rand = integer_to_list(binary:decode_unsigned(crypto:strong_rand_bytes(8)), 36),
    TempDir = filename:basedir(user_cache, Prefix),
    TempFile = filename:join(TempDir, Rand),
    []= os:cmd("mkdir " ++ "\"" ++ TempDir ++ "\""),
    {ok, _} = file:list_dir(TempDir),
    Result = file:write_file(TempFile, <<>>),
    case {Result} of
         {ok}    -> {ok, TempFile};
         {Error}  -> Error
    end.