Erlang에서 Temp Filename을 어떻게 만드나요?
문제
다른 함수가 파일을 입력으로 가져 오므로 파일에 데이터를 넣어야합니다.
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())
빠르고 쉬운 고유 한 innentifier를 위해. 최대 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 = 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 문자열로 변환하고, OS가 안전한 사용자-국소 임시 캐시 위치로 우리에게 반환되는 모든 것에 추가합니다.
물론 UNIX 유형 시스템에서 우리는 그냥 사용할 수 있습니다. filename:join(["/tmp", Prefix, Rand])
그러나 사용할 수없는 /tmp
Windows에서는 여기서 요점이 있습니다.