16.1.3 枚举目录中的内容
有时需要获得目录的内容列表。使用enumeratorAtPath:方法或者directoryContentsAtPath:方法,都可以完成枚举过程。如果使用第一种方法,一次可以枚举指定目录中的每个文件,默认情况下,如果其中一个文件为目录,那么也会递归枚举它的内容。在这个过程中,通过向枚举对象发送一条skipDescendants消息,可以动态地阻止递归过程,从而不再枚举目录中的内容。
对于directoryContentsAtPath:方法,使用这个方法,可以枚举指定目录的内容,并在一个数组中返回文件列表。如果这个目录中的任何文件本身是个目录,这个方法并不递归枚举它的内容。
代码清单16-4演示了如何在程序中使用这两个方法。
代码清单16-4
//Enumerate the contents of a directory
import<Foundation/NSString.h>
import<Foundation/NSFileManager.h>
import<Foundation/NSAutoreleasePool.h>
import<Foundation/NSArray.h>
int main(int argc, char*argv[])
{
NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];
NSString*path;
NSFileManager*fm;
NSDirectoryEnumerator*dirEnum;
NSArray*dirArray;
//Need to create an instance of the file manager
fm=[NSFileManager defaultManager];
//Get current working directory path
path=[fm currentDirectoryPath];
//Enumerate the directory
dirEnum=[fm enumeratorAtPath:path];
NSLog(@“Contents of%@:,path);
while((path=[dirEnum nextObject])!=nil)
NSLog(@,path);
//Another way to enumerate a directory
dirArray=[fm directoryContentsAtPath:
[fm currentDirectoryPath]];
NSLog(@“Contents using directoryContentsAtPath:);
for(path in dirArray)
NSLog(@,path);
[pool drain];
return 0;
}
代码清单16-4输出
Contents of/Users/stevekochan/mysrc/ch16:
a.out
dir1.m
dir2.m
file1.m
newdir
newdir/file1.m
newdir/output
path1.m
testfile
Contents using directoryContentsAtPath:
a.out
dir1.m
dir2.m
file1.m
newdir
path1.m
testfile
让我们仔细看看以下代码内容:
dirEnum=[fm enumeratorAtPath:path];
NSLog(@“Contents of%@:,path);
while((path=[dirEnum nextObject])!=nil)
NSLog(@,path);
通过向文件管理器对象(此处是fm)发送enumeratorAtPath:消息来开始目录的枚举过程。enumeratorAtPath:方法返回了一个NSDirectortyEnumerator对象,这个对象存储在dirEnum中。现在,每次向该对象发送nextObject消息时,都会返回所枚举的目录中下一个文件的路径。没有其他文件可供枚举过程使用时,会返回nil。
从代码清单16-4的输出中,可以看到这两种枚举技术的不同之处。enumeratorAtPath:方法列出了newdir目录中的内容,而方法directoryContentsAtPath:没有。如果newdir包含子目录,那么方法enumeratorAtPath:也会枚举其中的内容。
前面提到过,在代码清单16-4中while循环的执行过程中,通过对代码做如下更改,可以阻止任何子目录中的枚举。
while((path=[dirEnum nextObject])!=nil){
NSLog(@,path);
[fm fileExistsAtPath:path isDirectory:&flag];
if(flag==YES)
[dirEnum skipDescendents];
}
这里,flag是一个BOOL变量。如果指定的路径是目录,则fileExistsAtPath:在flag中存储yes,否则存储NO。
另外提醒一下,无需像在这个程序中那样进行快速枚举,使用以下NSLog调用可显示整个dirArray的内容:
NSLog(@,dirArray);