ディレクトリ・トラバース用ユーティリティ

30分プログラム、その685。ディレクトリ・トラバース用ユーティリティ。

指定したディクトリから、条件を満したファイルを探しだすコマンドを書くための、ユーティリティ関数を作りました。

loop()->
    receive
	{T,Path} ->
	    io:format("~p - ~p~n",[T, Path]),
	    loop();
	bye ->
	    bye
    end.

example()->
    traversal(self(),"/tmp"),
    loop().

traversal関数を呼ぶと、ディレクトリをトラバースするプロセスがたちあがります。あとは、パスがメッセージとして送られてくるので、それを処理してやればOKです。

使い方

loop()->
    receive
	{T,Path} ->
	    io:format("~p - ~p~n",[T, Path]),
	    loop();
	bye ->
	    bye
    end.

example()->
    traversal(self(),"/tmp"),
    loop().

実行例。

file - "/tmp/MobileDevice.log"
file - "/tmp/com.hp.launchport"
dir - "/tmp/launch-ZdaIqD"
dir - "/tmp/launch-rWDwL1"
dir - "/tmp/launch-y4t40N"
file - "/tmp/launch-ZdaIqD/Listeners"
dir - "/tmp/launchd-84.VUqUl4"
file - "/tmp/launch-rWDwL1/Render"
dir - "/tmp/screens"
file - "/tmp/launch-y4t40N/:0"
dir - "/tmp/ssh-Ojpt8bK6mC"
file - "/tmp/launchd-84.VUqUl4/sock"
dir - "/tmp/ssh-yMXqwluA6X"
dir - "/tmp/screens/S-mzp"
file - "/tmp/ssh-Ojpt8bK6mC/agent.191"
file - "/tmp/ssh-yMXqwluA6X/agent.206"

ソースコード

-module(traversal).
-compile([export_all]).

traversal_impl(Pid, Cwd) ->
    spawn(fun () ->
      lists:foreach(fun(Name) ->
	Path = filename:join(Cwd,Name),
	case filelib:is_dir(Path) of
	    true ->
		Pid ! start,
		Pid ! {dir,Path},
		traversal_impl(Pid,Path);
	    _ ->
		Pid ! {file,Path}
	end
      end,filelib:wildcard("*",Cwd)),
      Pid ! bye
    end).

wait_for_traversal(Pid,N) ->
    receive
	start ->
	    wait_for_traversal(Pid,N+1);
	bye ->
	    if N =:= 1 -> bye;
	       true    -> wait_for_traversal(Pid,N-1)
	    end;
	M ->
	    Pid ! M,
	    wait_for_traversal(Pid,N)
    end.

traversal(Pid, Cwd) ->
    spawn(fun()->
      traversal_impl(self(),Cwd),
      wait_for_traversal(Pid,0),
      Pid ! bye
    end).

loop()->
    receive
	{T,Path} ->
	    io:format("~p - ~p~n",[T, Path]),
	    loop();
	bye ->
	    bye
    end.

example()->
    traversal(self(),"/tmp"),
    loop().