遍历目录中的每个文件 [英] iterate through each file in a directory

查看:141
本文介绍了遍历目录中的每个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

erlang对我来说是一种奇怪的语言,本周我一直在玩多种语言,我经常来这里寻求帮助,现在我在erlang,我再次被卡住:)



基本上所有我想做的是以下,但在erlang:

 设置objFSO = Server.CreateObject(Scripting.FileSystemObject)
设置objFolder = objFSO.GetFolder(currentDirectory))

For objFolder每个objFile在objFolder.Files
做一些与文件
做别的东西
做更多的东西
下一个

我最接近的是:

  -export([main / 1])。 

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

显然,不工作,没有什么像我需要它是..但我试过许多方法和阅读很多例子,但是根本无法弄清楚一个解决方案,也许这种语言是不是这样的东西?



这是需要作为一个escript(erlang脚本)

解决方案

很难推荐使用哪种方法,因为你的做某事伪代码太模糊了。 >

有两种主要方式可以在Erlang功能语言中的一个列表中进行迭代: map fold



最大的问题在于:你想对文件做些什么?您想要为文件(例如,总文件大小或某些东西)总计一些东西,还是要为每个文件存储一些值(即,单独的每个文件大小),或者想要执行某些操作 / em>这些文件,你不在乎这些文件的返回值是什么(即重命名每个文件)?



我将给出一个快速的例子这里使用从文件返回的文件列表:list_dir / 1

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

折叠



这里我们将使用列表来共享目录中所有文件的文件大小:foldl (as @legoscia提到,在这种情况下, filelib:fold_files 可能是更好的选择)

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

映射



在这里,我们将使用列表获取文件名列表以及每个单独文件的文件大小:map 。结果列表将是格式= [{somefile.txt,452},{anotherfile.exe,564},...]

  FileSizes =列表:map(fun(Filename) - > 
FileInfo = file:read_file_info(some_directory /+ +文件名),
FileSize = FileInfo#file_info.size,
{Filename,FileSize}
end,Filenames)。

Foreach (映射的变体)



只是重命名文件,但不关心记录文件的任何数据的替代方法是演示使用列表:foreach ,这通常是专门用于副作用编程,其中您不关心返回值,它的工作原理像列表:map ,但不返回任何有用的东西(它只是返回原子 ok ):



在这种情况下,我将显示通过添加重命名每个文件。旧的扩展名到每个文件名:

 列表:foreach(fun(Filename))> 
OldFile =some_directory /++文件名,
NewFile = OldFile ++.old,
文件:rename(OldFile,NewFile),
end,Filenames)。

递归



当然,所有这些的原始版本 - 如果 map fold foreach 或列表推导(我没有覆盖,但基本上是地图的另一个变体, / code>组件)由于任何原因太限制 - 您可以递归地执行事情:

  do_something_with_files([]) - >好; 
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)。 


erlang is a strange language to me, this week i've been playing with multiple languages and I've come here for help often, now I'm on erlang and I'm stuck once again :)

Basically All i'm trying to do is the following but in 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

The closest i've come is:

-export([main/1]).

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

clearly, not working and nothing like how i'd need it to be.. but I have tried many ways and read many example but simply cant figure out a solution maybe the language just isnt ment for this kind of stuff?

And this is needed as a escript (erlang script)

解决方案

It's tough to recommend exactly which method you should use because your "do something" pseudocode is too vague.

There are two main ways one iterates over a list of something in a functional language like Erlang: map and fold.

The big question comes down to this: What do you want to do with the files? Do you want to total something up for the files (ie, total file size or something), or do you want to store some value for each file (ie each file size individually) or do you want to do something to the files and you don't care what the return values for those files are (ie renaming each file)?

I'll give an example of each quickly here using a list of files returned from file:list_dir/1:

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

Folding

Here we'll total the filesizes of all files in the directory using lists:foldl (as @legoscia mentioned, in this case, filelib:fold_files is probably the better choice)

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

Mapping

Here, we'll get a list of filenames along with the filesize for each individual file using lists:map. The resultant list will be of the format = [{"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 (a variant of mapping)

The alternative of just renaming files but not caring about recording any data about the files is to demonstrate the use of lists:foreach, which is generally used exclusively for side-effect programming in which you don't care about the return values, and it works like lists:map, but doesn't return anything useful (it just returns the atom ok):

In this case, I'll show renaming each file by adding a ".old" extension to each filename:

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

Recursion

Of course, the raw version of all of these - if map, fold, foreach, or list comprehensions (which I didn't cover, but are basically another variant of map with a filter component) are too restricting for whatever reason - you can do things recursively:

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

There are a lot of ways to do what you need with Erlang, but unlike with procedural languages like VB, you must think a little ahead to what you want to track or do in order to determine how you wish to iterate over your lists, since you're limited by immutable variables in Erlang.

Note: In order to use the #file_info record, you'll need to include the file.hrl file at the top of your module with:

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

这篇关于遍历目录中的每个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆