早期,目录就是一个包含有文件名和磁盘分配表的正常文件,可以像其他文件一样打开和读取目录文件,由于效率的需求以及各种不同文件系统的存在,开发人员创建了一些特殊的函数用来打开,读取,关闭目录.
不仅可以获取文件名和目录名列表,也可以获取文件和目录的相当一部分信息.下面的示例列出了目录中的所有文件名和子目录名,并且对每一项显示了一些信息.
结构体stat中可以获取的信息的详细内容,可以通过在终端键入:man 2 stat来查看.
/* showdir.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
DIR *dir;
struct dirent *dent;
struct stat st;
char *directory_name = ".";
char file_name[120];
if (argc > 1)
directory_name = argv[1];
//调用函数opendir()打开目录,返回一个DIR型的数据作为句柄以操作目录
if ((dir = opendir(directory_name)) == NULL) {
perror("Cannot open directory");
return 1;
}
//调用函数readdir()读取目录的每一项(头两项总是”.”和”..”)
while (dent = readdir(dir)) {
printf("the object: %s\n", dent->d_name);
sprintf(file_name, "%s/%s", directory_name, dent->d_name);
//调用函数stat()来获取文件信息,返回信息在结构体st中
if (stat(file_name, &st) < 0) {
perror("Cannot get file status");
errno = 0;
continue;
}
printf(" A ");
if (S_ISLNK(st.st_mode))
printf("symbolic link");
if (S_ISREG(st.st_mode))
printf("regular file");
if (S_ISDIR(st.st_mode))
printf("directory");
if (S_ISCHR(st.st_mode))
printf("character device");
if (S_ISBLK(st.st_mode))
printf("block device");
if (S_ISFIFO(st.st_mode))
printf("fifo");
if (S_ISSOCK(st.st_mode))
printf("socket");
printf("\n");
printf(" Owner group: %d user: %d\n",
st.st_gid, st.st_uid);
printf(" File size in bytes: %d\n", st.st_size);
printf(" Accessed: %d", ctime(&st.st_atime));
printf(" Modified: %d\n\n", ctime(&st.st_mtime));
errno = 0;
}
if (errno != 0)
perror("Cannot read directory entry");
//调用函数closedir()来关闭目录
closedir(dir);
return 0;
}