很难准确地推荐您应该使用哪种方法,因为您的“做某事”伪代码太模糊了。
有两种主要的方法,一种是在像 Erlang 这样的函数式语言中迭代一个列表:map
和fold
.
最大的问题归结为:您想对这些文件做什么?您是要对文件进行汇总(即总文件大小或其他内容),还是要为每个文件存储一些值(即每个文件大小单独),还是要对文件做一些事情,然后您不在乎这些文件的返回值是什么(即重命名每个文件)?
我将使用从以下位置返回的文件列表快速给出每个示例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 map
、fold
、foreach
或列表推导(我没有介绍,但基本上是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").