UNIX 文件系统基本操作( 三 )
清单 3. 处理一个目录
unsigned process_directory( char *theDir )
{
DIR *dir = NULL;
struct dirent entry;
struct dirent *entryPtr = NULL;
int retval = 0;
unsigned count = 0;
char pathName[PATH_MAX1];
/* Open the given directory, if you can. */
dir = opendir( theDir );
if( dir == NULL ) {
printf( "Error opening %s: %s", theDir, strerror( errno ) );
return 0;
}
在打开了指定的目录之后,调用 readdir_r()(请参见清单 4)以获取关于第一个条目的信息,随后每次调用 readdir_r() 都将返回下一个条目,直到到达了目录末尾,并且 entryPtr 被设置为 NULL 。这里还使用了 strncmp() 来检查“.和“..条目,以便略过它们 。如果不略过它们,您将永远都在处理类似“theDir/./././././././././.等这样的目录 。
清单 4. 读取一个目录条目
retval = readdir_r( dir, &entry, &entryPtr );
while( entryPtr != NULL ) {
struct stat entryInfo;
if( ( strncmp( entry.d_name, ".", PATH_MAX ) == 0 ) ||
( strncmp( entry.d_name, "..", PATH_MAX ) == 0 ) ) {
/* Short-circuit the . and .. entrIEs. */
retval = readdir_r( dir, &entry, &entryPtr );
continue;
}
既然已经得到了目录的条目名称,那么您需要构造一个更加完整的路径(请参见清单 5),然后调用 lstat() 以获取该条目的相关信息 。因为符号链接需要特殊的处理,所以这里使用了 lstat() 函数 。您可以使用 readlink() 函数找到其目标文件 。
如果该条目是一个目录,那么对这个目录递归地调用 process_Directory(),并将其中所找到的条目数加到运行总数中 。如果该条目是一个文件,那么显示其名称和字节数(可在 struct stat 的 st_size 成员中找到) 。
清单 5. 处理条目
(void)strncpy( pathName, theDir, PATH_MAX );
(void)strncat( pathName, "/", PATH_MAX );
(void)strncat( pathName, entry.d_name, PATH_MAX );
if( lstat( pathName, &entryInfo ) == 0 ) {
/* stat() succeeded, let's party */
count;
if( S_ISDIR( entryInfo.st_mode ) ) {
/* directory */
printf( "processing %s/n", pathName );
count= process_directory( pathName );
} else if( S_ISREG( entryInfo.st_mode ) ) {
/* regular file */
printf( "t%s has %lld bytesn",
pathName, (long long)entryInfo.st_size );
} else if( S_ISLNK( entryInfo.st_mode ) ) {
/* symbolic link */
char targetName[PATH_MAX1];
if( readlink( pathName, targetName, PATH_MAX ) != -1 ) {
printf( "t%s -> %sn", pathName, targetName );
} else {
printf( "t%s -> (invalid symbolic link!)n",
pathName );
}
}
} else {
printf( "Error statting %s: %sn", pathName, strerror(
errno ) );
}
在 while 循环的底部,读取另一个目录条目并对其进行处理 。如果您完成了对目录条目的处理,那么关闭当前打开的目录,并返回经过处理的条目的数目 。
清单 6. 读取另一个条目
retval = readdir_r( dir, &entry, &entryPtr );
}
/* Close the Directory and return the number of entrIEs. */
(void)closedir( dir );
return count;
}
最后,清单 7 显示了该程序的 main() 函数,它只是对命令行中传递的每个参数调用了 process_directory() 函数 。一个真正的程序应该具有使用方法消息,并且在用户没有指定任何参数时,提供某种形式的反馈信息,但我把这项内容作为练习留给读者 。
清单 7. 主线
/* readdir_demo main()
*
* Run through the specified directories, and pass them
* to process_directory().
*/
int main( int argc, char **argv )
{
int idx = 0;
unsigned count = 0;
for( idx = 1; idx < argc; idx) {
count= process_directory( argv[idx] );
推荐阅读
- UNIX 新手指南,第 3 部分:正则表达式
- UNIX 新手指南,第 2 部分: vi 文本编辑器
- UNIX 新手指南: 一些很好的 Shell 诀窍
- 使用 UNIX System V IPC 机制共享应用程序数据
- 利用 UNIX 脚本来管理 DS4000 磁盘阵列系统
- 对话 UNIX,第 13 部分: 另外十种命令行组合
- UNIX 生产力技巧
- UNIX 新手指南,第 1 部分: 文件维护工具
- 使用 UNIX find 命令的高级技术
- 对话 UNIX: 更多 shell 脚本技术