他の関数はファイルを入力として受け取るため、データをファイルに入れる必要があります。
Erlangで一意のファイル名を作成するにはどうすればよいですか?
UNIXの「tempfile」のようなものは存在しますか?
実際のファイル名を生成するだけですか?その場合、最も安全な方法は、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])).
"nonode@nohost-1249.304278.322000"
4>
使用することもできますTMP = lib:nonl(os:cmd("mktemp")).
またはあなたはすることができます
erlang:phash2(make_ref())
すばやく簡単な一意の識別子。最大2^82の呼び出しに固有であり、目的には十分です。これは、使用するノード名でタイムスタンプをフォーマットするよりも簡単だと思います。
遅い答え:スクラッチディレクトリをサポートしているtest_serverモジュールに気づきました。一見の価値があります
私はついにこの問題を抱えました-そして私のユーザーは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文字列に変換して、OSが安全なユーザーローカル一時キャッシュの場所として返すものに追加します。
もちろん、UNIXタイプのシステムでは、使用することもできますfilename:join(["/tmp", Prefix, Rand])
が、/tmp
Windowsで使用できないことは、ここでの要点の1つです。
OTP24にはありません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.