5

erlang は私にとって奇妙な言語です。今週、私は複数の言語で遊んでいて、頻繁に助けを求めてここに来ました。

基本的に私がやろうとしているのは次のことですが、erlangでは次のとおりです。

Dim objFSO, objFile, objFolder

Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(currentDirectory))

For Each objFile in objFolder.Files
   do something with the file
   do something else
   do more stuff
Next

私が来た最も近いものは次のとおりです。

-export([main/1]).

main([]) -> 
find:files("c:\","*.txt", fun(F) -> {
       File, c:c(File)
}end).

明らかに、機能しておらず、必要な方法は何もありません..しかし、私は多くの方法を試し、多くの例を読みましたが、単に解決策を見つけられないだけかもしれません。

そして、これは escript (erlang スクリプト) として必要です。

4

2 に答える 2

11

「何かを行う」疑似コードが曖昧すぎるため、どの方法を使用すべきかを正確に推奨することは困難です。

Erlang のような関数型言語で何かのリストを反復処理するには、主に 2 つの方法があります:mapfold.

大きな問題は次のようになります。ファイルをどうしたいですか? ファイルを合計したいですか (つまり、ファイルの合計サイズか何か)、それともファイルごとに値を保存したいですか (つまり、各ファイル サイズを個別に)、またはファイルに対して何かをしたいと思いますか?それらのファイルの戻り値が何であるか (つまり、各ファイルの名前を変更すること) は気にしませんか?

から返されたファイルのリストを使用して、ここでそれぞれの例を簡単に示しますfile:list_dir/1

{ok, Filenames} = file:list_dir("some_directory"),

折りたたみ

ここでは、ディレクトリ内のすべてのファイルのファイルサイズを合計しますlists:foldl(@legoscia が言及したように、この場合filelib:fold_filesはおそらくより良い選択です)

TotalSize = lists:foldl(fun(Filename,SizeAcc) ->
                FileInfo = file:read_file_info("some_directory/" ++ Filename),
                FileSize = FileInfo#file_info.size,
                SizeAcc + FileSize
            end, 0, Filenames).

マッピング

ここでは、ファイル名のリストと、lists:map. 結果のリストは = の形式になります[{"somefile.txt",452}, {"anotherfile.exe",564},...]

FileSizes = lists:map(fun(Filename) ->
                FileInfo = file:read_file_info("some_directory/" ++ Filename),
                FileSize = FileInfo#file_info.size,
                {Filename,FileSize}
            end,Filenames).

Foreach (マッピングの一種)

ファイルの名前を変更するだけで、ファイルに関するデータの記録を気にしないという代替案は、 の使用を示すことですlists:foreach。これは通常、戻り値を気にしない副作用プログラミングにのみ使用され、 のように動作しますlists:map。しかし、有用なものは何も返しません (atom を返すだけですok):

この場合、各ファイル名に「.old」拡張子を追加して、各ファイルの名前を変更する方法を示します。

lists:foreach(fun(Filename) ->
                  OldFile = "some_directory/" ++ Filename,
                  NewFile = OldFile ++ ".old",
                  file:rename(OldFile, NewFile), 
              end,Filenames).

再帰

もちろん、これらすべての生のバージョン - if mapfoldforeach、またはリスト内包表記 (これはカバーしませんでしたが、基本的にコンポーネントをmap使用した別のバリアントfilterです) は何らかの理由で制限が多すぎます - 再帰的に行うことができます:

do_something_with_files([]) -> ok;
do_something_with_files([CurrentFile|RestOfFiles]) ->
   do_something(CurrentFile),
   do_something_with_files(RestOfFiles).

Erlang で必要なことを行う方法はたくさんありますが、VB のような手続き型言語とは異なり、リストをどのように反復処理するかを決定するために、何を追跡または実行したいかを少し先に考える必要あります。Erlang の不変変数によって制限されています。

注:レコードを使用する#file_infoには、モジュールの先頭に次のように file.hrl ファイルを含める必要があります。

-include_lib("kernel/include/file.hrl").
于 2013-01-22T00:10:51.837 に答える
2

私は最近ファイルシステムインデクサーを作成しました。以下に、ディレクトリをトラバースできるモジュールを提供します。このモジュールを使用すると、検索したファイルや検索したフォルダーを自由に使用できます。それが行うことは、それがspawn任意の内部ディレクトリを処理するための新しいプロセスになるということです。2つを提供します。1つFunctional Objectsはディレクトリを処理し、もう1つはファイルを処理します。

%% @docこのモジュールは、読み取り、書き込み、
%%ディレクトリ内での検索、結合、および移動。
%% @終わり
-module(file_scavenger_utilities)。 %%%-------エクスポート--------------------------------------- ---------------------------------------- -compile(export_all)。 %%%-------含まれるもの--------------------------------------- -------------------------------------- %%% -------- MACROS -------------------------------------- ---------------------------------------- -define(IS_FOLDER(X)、filelib:is_dir(X))。 -define(IS_FILE(X)、filelib:is_file(X))。 -define(FAILED_TO_LIST_DIR(X)、 error_logger:error_report([" *ファイルスカベンジャーユーティリティエラー* "、 {エラー、 "ディレクトリの一覧表示に失敗しました"}、{ディレクトリ、X}]))。 -define(NOT_DIR(X)、 error_logger:error_report([" *ファイルスカベンジャーユーティリティエラー* "、 {エラー、 "ディレクトリではありません"}、{申し立てられた、X}]))。 -define(NOT_FILE(X)、 error_logger:error_report([" *ファイルスカベンジャーユーティリティエラー* "、 {エラー、 "ファイルではありません"}、{申し立てられた、X}]))。 %%% - - - - - タイプ - - - - - - - - - - - - - - - - - - - ------------------------------------------
%% @type dir()= string()。 %%バックスラッシュではなく、スラッシュを含める必要があります。スラッシュで終わらせてはいけません 正確なディレクトリの後の%%。例:これは間違っています: "C:/ Program Files / SomeDirectory /" %%ですが、これは正しいです: "C:/ Program Files / SomeDirectory" %% @type file_path()= string()。 %%バックスラッシュではなく、スラッシュを含める必要があります。 %%「C:/ProgramFiles/SomeFile.pdf」などのファイル拡張子も含める必要があります %% ------------------------------------------------ -----------------------------------------------
%% @ docディレクトリに入り、見つかったファイルごとに楽しいForEachFileFound/2を実行します %%ディレクトリが見つかると、楽しい%% ForEachDirFound/2を実行します。 %%上記の両方の楽しみは、最初の引数として親Dirを取ります。次に、それはスポーンします 親ディレクトリと同じ方法で見つかったディレクトリも拡散する%%erlangプロセス %%が広がりました。拡散のプロセスは、すべてのファイル(ネストされているかどうかに関係なく)まで継続します。 %% Directory)は、そのフルパスで登録されます。 %% @終わり %% %% @spec new_user(dir()、funtion()、function())->ok。

Spread_directory(Dir、Top_Directory、ForEachFileFound、ForEachDirFound) is_function(ForEachFileFound)、is_function(ForEachDirFound)->の場合 ケース?IS_FOLDER(Dir)of false->?NOT_DIR(Dir); true-> F = fun(X)-> FileOrDir = filename:absname_join(Dir、X)、 の場合?IS_FOLDER(FileOrDir) true-> (ForEachDirFound(Top_Directory、FileOrDir)をキャッチ)、 spawn(fun()-> ?MODULE:spread_directory(FileOrDir、Top_Directory、ForEachFileFound、ForEachDirFound) 終わり); false-> の場合?IS_FILE(FileOrDir) false-> {error、not_a_file、FileOrDir}; true->(ForEachFileFound(Top_Directory、FileOrDir)をキャッチします) 終わり 終わり 終わり、 ケースファイル:
{error、_}のlist_dir(Dir)->?FAILED_TO_LIST_DIR(Dir); {ok、List}-> lists:foreach(F、List) 終わり 終わり。

それをテストするために、以下は使用法です:

E:\ Applications> erl
Eshell V5.9(^ Gで中止)
1> Dir = "E:/Ruth"。
「E:/ルース」
2> TopDir = "E:/Ruth"。
「E:/ルース」
3> Folder = fun(Parent、F)-> io:format( "\ n \ t〜p contains Folder:〜p〜n"、[Parent、F])end。
#Fun <erl_eval.12.111823515>
4> File = fun(Parent、F)-> io:format( "\ n \ t〜p contains File:〜p〜n"、[Parent、F])end。
#Fun <erl_eval.12.111823515>
5> file_scavenger_utilities:spread_directory(Dir、TopDir、File、Folder)。

    "E:/Ruth" contains File: "e:/Ruth/Thumbs.db"        

    "E:/Ruth" contains File: "e:/Ruth/Robert Passport.pdf"

    "E:/Ruth" contains File: "e:/Ruth/new mixtape.mp3"

    "E:/Ruth" contains File: "e:/Ruth/Manning - Java 3d Programming.pdf"

    "E:/Ruth" contains File: "e:/Ruth/jcrea350.zip"

    "E:/Ruth" contains Folder: "e:/Ruth/java-e books"

    "E:/Ruth" contains File: "e:/Ruth/Java Programming Unleashed.pdf"        

    "E:/Ruth" contains File: "e:/Ruth/Java Programming Language Basics.pdf"

    "E:/Ruth" contains File: "e:/Ruth/java-e books/vb blackbook.pdf.pdf"

于 2013-01-22T07:03:45.837 に答える