通过在目录中的每个文件迭代(iterate through each file in a direc

2019-08-07 17:15发布

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(二郎脚本)

Answer 1:

这很难确切地建议你应该用哪一种方法,因为你的“做什么”伪太模糊。

有两种主要途径之一迭代的东西名单像二郎函数式语言: mapfold

最大的问题归结为:你想干什么用的文件呢? 你想总的东西了的文件(即,文件总大小什么的),或者你想保存每个文件的一些值(即每个单独的文件大小)或你想做些什么的文件和你不在乎这些文件的返回值(即重命名每个文件)?

我给这里很快利用返回的文件列表中的每个示例file:list_dir/1

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

折页

在这里,我们将使用总的所有文件的filesizes目录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 ,但不返回任何有用的东西(它只是返回的原子ok ):

在这种情况下,我将展示通过添加一个“.old为”延伸到每个文件名重命名每个文件:

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

递归

当然,所有这些的原始版本-如果mapfoldforeach或列表解析(我没有涉及,但基本上另一种变体mapfilter组件)的限制也不管是什么原因-你可以做事递归:

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

有很多方法可以做到你需要使用Erlang什么,但不像像VB程序语言,你一定觉得有点超前到你想跟踪或者为了做什么 ,以确定你希望如何遍历您的名单,因为你在二郎不可改变变量的限制。

注:为了使用#file_info记录,您将需要包括你的模块的顶部file.hrl文件:

-include_lib("kernel/include/file.hrl").


Answer 2:

最近,我在这里下面,我为你提供一个模块,它可以遍历目录(S)写了一个文件系统索引,让你永远这样你想要找到的文件,或者找到的文件夹中的内容。 它所做的是,它会spawn一个新的进程来处理任何内部目录。 您将提供两种Functional Objects ,一个将处理目录和其他将处理文件。

  %% @doc该模块提供了低级别的API用于读取,写入,  %%搜索,加入和目录内移动。  %% @结束 
-module(file_scavenger_utilities)。 %%% ------- EXPORTS --------------------------------------- ---------------------------------------- -compile(export_all)。 %%% ------- INCLUDES --------------------------------------- -------------------------------------- %%% --------宏-------------------------------------- ---------------------------------------- -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()=串()。 %%必须是包含正斜杠,而不是反斜杠。 不能以斜线结束 %%确切directory.eg后,这是错误的: “C:/ Program Files文件/ SomeDirectory /” %%但这是正确的: “C:/ Program Files文件/ SomeDirectory” %% @type FILE_PATH()=串()。 %%必须是包含正斜杠,而不是反斜杠。 %%应包括文件扩展名,以及如“C:/ Program Files文件/ SomeFile.pdf的” %% ------------------------------------------------ -----------------------------------------------
%% @doc进入目录并执行乐趣,为它找到的每个文件ForEachFileFound / 2 %%如果找到一个目录,它执行的乐趣%% ForEachDirFound / 2。 上述两种%%采取玩意儿父Dir,作为第一个参数。 然后,将产生的 %% Erlang进程会以同样的方式传播发现目录也作为父目录 %%被传播。 传播的过程不断进行,直到每个文件(阉其嵌套 %%目录)是由它的完整路径注册。 %% @结束 %% %% @spec new_user(DIR(),funtion(),函数()) - >确定。

spread_directory(DIR,Top_Directory,ForEachFileFound,ForEachDirFound)时is_function(ForEachFileFound),is_function(ForEachDirFound) - >情况下IS_FOLDER虚假的(DIR) - > NOT_DIR(DIR)?; 真正的 - > F =乐趣(X) - > FileOrDir =文件名:absname_join真(迪尔,X),案例IS_FOLDER(FileOrDir) - >(赶上ForEachDirFound(Top_Directory,FileOrDir)),产卵(乐趣() - >? MODULE:spread_directory(FileOrDir,Top_Directory,ForEachFileFound,ForEachDirFound)端); 假 - >情况下的IS_FILE假(FileOrDir) - > {错误,not_a_file,FileOrDir}?; 真 - >(赶上ForEachFileFound(Top_Directory,FileOrDir))结束端结束,案卷:list_dir(DIR)的
?{错误,_} - > FAILED_TO_LIST_DIR(DIR); 【OK,列表} - >列表:的foreach(F,列表)结束端。

为了测试它,下面是用法:

  E:\应用> ERL  ESHELL V5.9(与中止^ G)  1>风向= “E:/露丝”。  “E:/露丝”  2> TOPDIR = “E:/露丝”。  “E:/露丝”  3>文件夹=乐趣(父,F) - > IO:格式( “\ n \吨〜p包含文件夹:〜p〜n的”,[父,F])端。  #Fun <erl_eval.12.111823515>  4>文件=乐趣(父,F) - > IO:格式( “\ n \吨〜p包含文件:〜P〜N”,[父,F])端。  #Fun <erl_eval.12.111823515>  5> file_scavenger_utilities:spread_directory(DIR,TOPDIR,文件,文件夹)。 

    "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"



文章来源: iterate through each file in a directory
标签: erlang