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

发布于 2024-07-29 08:38:16 字数 103 浏览 3 评论 0原文

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

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

是否存在像unix“tempfile”这样的东西?

I need to put data in a file since my other function takes a file as input.

How do I create a unique filename in Erlang?

Does something like unix "tempfile" exist?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一人独醉 2024-08-05 08:38:16

您的意思是只生成实际的文件名吗? 在这种情况下,最安全的方法是混合使用从 now() 获得的数字和计算机的主机名(如果您有多个节点执行相同的操作)。

就像是:

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])).
"[email protected]"
4> 

Do you mean just generate the acutal filename? In that case the safest way would be to use a mix of the numbers you get from now() and the hostname of your computer (if you have several nodes doing the same thing).

Something like:

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])).
"[email protected]"
4> 
茶花眉 2024-08-05 08:38:16

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

You can also use TMP = lib:nonl(os:cmd("mktemp")).

安静 2024-08-05 08:38:16

或者您可以使用

erlang:phash2(make_ref())

来获得快速且简单的唯一标识符。 最多可进行 2^82 次调用,这应该足以满足您的目的。 我发现这比使用节点名称格式化时间戳更容易。

Or you could do

erlang:phash2(make_ref())

for a quick and easy unique indentifier. Unique for up to 2^82 calls which should be enough.for your purposes. I find this easier than formatting a timestamp with node name for use.

寂寞美少年 2024-08-05 08:38:16

迟到的答案:我刚刚注意到 test_server 模块具有暂存目录支持,值得一看

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

Late answer: I just noticed the test_server module which has scratch directory support, worth a look

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

蹲墙角沉默 2024-08-05 08:38:16

我终于遇到了这个问题 - 而且我的用户混合使用 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 = filelib: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 = filelib: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]),但在 Windows 上 /tmp 不可用这就是重点。

I've finally had this problem -- and my user is using a mix of Windows and Linux systems, so the old tried-and-true lib:nonl(os:cmd("mktemp")) method is just not going to cut it anymore.

So here is how I've approached it, both with a mktemp/1 function that returns a filename that can be used and also a mktemp_dir/1 function that returns a directory (after having created it).

-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 = filelib:ensure_dir(TempFile),
    Result2 = file:write_file(TempFile, <<>>),
    case {Result1, Result2} of
         {ok, ok}    -> {ok, TempFile};
         {ok, Error} -> Error;
         {Error, _}  -> Error
    end.

And the directory version:

-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 = filelib:ensure_dir(TempDir),
    Result2 = file:make_dir(TempDir),
    case {Result1, Result2} of
         {ok, ok}    -> {ok, TempDir};
         {ok, Error} -> Error;
         {Error, _}  -> Error
    end.

Both of these do basically the same thing: we get a strongly random name as a binary, convert that to a base36 string, and append it to whatever the OS returns to us as a safe user-local temporary cache location.

On a unix type system, of course, we could just use filename:join(["/tmp", Prefix, Rand]) but the unavailability of /tmp on Windows is sort of the whole point here.

雨巷深深 2024-08-05 08:38:16

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

In OTP 24 there is not file:ensure_dir. So I've made something similar:

For directory:

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.

For file:

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文