Chinaunix首页 | 论坛 | 博客
  • 博客访问: 347604
  • 博文数量: 60
  • 博客积分: 1570
  • 博客等级: 上尉
  • 技术积分: 620
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-02 23:37
文章分类

全部博文(60)

文章存档

2012年(2)

2010年(2)

2009年(56)

分类: LINUX

2009-11-21 15:06:00

一、遍历目录函数:ftw 和 nftw

 Solaris 和 Linux中, 函数ftw 遍历目录,对于每一个文件,它都会调用一个用户定义的函数。ftw函数的问题是:对于每一个文件,它都会调用 stat函数,这就使程序跟随符号链接(因为stat 函数是跟随符号链接的)。例如,如果从 root 开始,并且有一个名为 /lib 的符号链接,它指向 /usr/lib, 则所有在目录 /usr/lib 中的文件都会计数两次。为了纠正这一点,Solaris 和 Linux 提供了另一个函数 nftw, 它具有一个停止跟随符号链接的选项(通过把最后一个参数设置为 FTW_PHYS)。

APUE2中说:

    在 Single UNIX Specification 中,ftw 和 nftw 都包含在基本 POSIX.1 标准的XSI扩展中。Solaris 9 和 Linux 2.4.22都包含了他们的实现(以后的版本也应该包含了这两个函数吧 :) )。但是 基于 BSD 的UNIX 系统不包括这两个函数,它有另外一个函数 fts, 它提供类似的功能。 该函数在FreeBSD 5.2.1、MAC OS X 10.3 和 Linux2.4.22 中是可用的。

下面是 ftw 的用法的简单示例:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ftw.h>

int showfile(const char *file, const struct stat *stat, int type)
{
        switch(type) {
                case FTW_F:
                        switch (stat->st_mode & S_IFMT) {
                                case S_IFREG: printf("%s -- regular file\n", file); break;
                                case S_IFCHR: printf("%s -- character special file\n", file); break;
                                case S_IFBLK: printf("%s -- block special file\n", file); break;
                                case S_IFIFO: printf("%s -- pipe or FIFO\n", file); break;

                                /* 因为 ftw 函数跟随符号链接,所以下面的这个条件永远无法满足 */
                                case S_IFLNK: printf("%s -- symbolic link\n", file); break;
                                case S_IFSOCK: printf("%s -- socket\n", file); break;
                                case S_IFDIR:
                                               printf("for S_IFDIR for %s: %m\n", file);
                                               break;
                        }
                        break;
                case FTW_D: printf("%s -- directory file\n", file); break;
                case FTW_DNR: printf("%s -- can't read directory\n", file); break;
                case FTW_NS: printf("%s -- stat error: %m\n", file); break;
                default: printf("unknown type %d for file: %s\n", type, file);
        }
        return 0;
}

/* Simple example of usage of ftw function */
int main(int argc, char *argv[])
{
        assert(argc == 2);

        if (ftw(argv[1], showfile, 512) == -1)
                perror("ftw error");

        exit(0);
}


 
下面是 nftw 函数用法的简单示例:
 

#define _XOPEN_SOURCE 500

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ftw.h>

int showfile(const char *file, const struct stat *stat, int type, struct FTW *ftwbuf)
{
        switch(type) {
                case FTW_F:
                        switch (stat->st_mode & S_IFMT) {
                                case S_IFREG: printf("%s -- regular file\n", file); break;
                                case S_IFCHR: printf("%s -- character special file\n", file); break;
                                case S_IFBLK: printf("%s -- block special file\n", file); break;
                                case S_IFIFO: printf("%s -- pipe or FIFO\n", file); break;

                                /* 当为符号链接时,这里判断不出来,不甚明白 */
                                case S_IFLNK: printf("%s -- symbolic link\n", file); break;
                                case S_IFSOCK: printf("%s -- socket\n", file); break;
                                case S_IFDIR:
                                               printf("for S_IFDIR for %s: %m\n", file);
                                               break;
                        }
                        break;
                case FTW_D: printf("%s -- directory file\n", file); break;
                case FTW_DNR: printf("%s -- can't read directory\n", file); break;
                case FTW_NS: printf("%s -- stat error: %m\n", file); break;

                /* 当为符号链接时,用这个条件才能判断出来 */
                case FTW_SL: printf("%s -- symbolic link by FTW_PHYS\n", file); break;
                case FTW_SLN: printf("%s -- symbolic link pointing to a nonexistent file\n", file); break;
                default: printf("unknown type %d for file: %s\n", type, file);
        }
        return 0;
}

/* Simple example of usage of ftw function */
int main(int argc, char *argv[])
{
        assert(argc == 2);

        if (nftw(argv[1], showfile, 512, FTW_PHYS) == -1)
                perror("ftw error");

        exit(0);
}


 
二、 目录操作函数: opendir readdir rewinddir closedir telldir seekdir
 
 
 

#include <dirent.h>
DIR *opendir(const char *pathname);
                              Returns: pointer if OK, NULL on error
 

struct dirent *readdir(DIR *dp);
                              Returns: pointer if OK, NULL at end of directory or error
 
void rewinddir(DIR *dp);

int closedir(DIR *dp);

                        Returns: 0 if OK, 1 on error
 

long telldir(DIR *dp);
                        Returns: current location in directory associated with dp 
 
void seekdir(DIR *dp, long loc);


 
练习上面的几个函数,用它们实现类似 nftw 的功能。
示例代码:
 
 
 
 
阅读(2102) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~