本文共 7559 字,大约阅读时间需要 25 分钟。
改变目录或文件的访问权限:
#includeint chmod(const char* path, mode_t mode); //path 参数指定的文件被修改为具有 mode 参数给出的访问权限
获取、改变当前目录:
#include//头文件 char *getcwd(char *buf, size_t size); //获取当前目录,相当于 pwd 命令 int chdir(const char *path); //修改当前目录,即切换目录,相当于 cd 命令
getcwd()函数: 将当前的工作目录绝对路径复制到参数 buf 所指的内存空间, 参数 size 为 buf
的空间大小。倘若参数 buf 为 NULL,getcwd()会依参数 size 的大小自动配置内存(使用malloc()),如果参数 size 也为 0,则 getcwd()会 依工作目录绝对路径的字符串程度来决定所配置的内存大小,进程可以在使用完此字符串后自动利用 free()来释放此空间。所以常用的形式:getcwd(NULL, 0)。 chdir()函数:用来将当前的工作目录改变成以参数 path 所指的目录。#includeint main() { chdir(“/tmp”); printf(“current working directory: %s\n”,getcwd(NULL,0)); return 0;}
创建和删除目录:
#include#include #include int mkdir(const char *pathname, mode_t mode); //创建目录,mode 是目录权限 int rmdir(const char *pathname); //删除目录
获取目录信息:
#include#include DIR *opendir(const char *name); //打开一个目录 struct dirent *readdir(DIR *dir); //读取目录的一项信息,并返回该项信息的结构体指针 void rewinddir(DIR *dir); //重新定位到目录文件的头部 void seekdir(DIR *dir,off_t offset); //用来设置目录流目前的读取位置 off_t telldir(DIR *dir); //返回目录流当前的读取位置 int closedir(DIR *dir); //关闭目录文件
seekdir()用来设置参数dir目录流读取位置,在调用readdir()时便从此新位置开始读取。参数offset 代表距离目录文件开头的偏移量。
读取目录信息的步骤为: 1、用 opendir 函数打开目录; 2、使用 readdir 函数迭代读取目录的内容,如果已经读取到目录末尾,又想重新开始读,则可以使用 rewinddir 函数将文件指针重新定位到目录文件的起始位置; 3、用 closedir 函数关闭目录 案例:#includeint main(int argc, char* argv[]){ ARGS_CHECK(argc, 2); DIR* dir; dir = opendir(argv[1]); ERROR_CHECK(dir, NULL, "opendir"); struct dirent *p; while(p = readdir(dir)) { printf("Ino = %ld len = %d type = %d filename = %s\n", p->d_ino, p->d_reclen, p->d_type, p->d_name); } closedir(dir); return 0;}
案例:
#includeint main(int argc, char* argv[]){ ARGS_CHECK(argc, 2); DIR* dir; dir = opendir(argv[1]); //打开一个目录,返回指向该目录流DIR的指针 ERROR_CHECK(dir, NULL, "opendir"); struct dirent *p; off_t pos; while(p = readdir(dir)) //读取目录的一项信息,并返回该项信息的结构体指针 { printf("Ino = %ld len = %d type = %d filename = %s\n", p->d_ino, p->d_reclen, p->d_type, p->d_name); if(!strcmp(p->d_name,"a.out")) { pos = telldir(dir); //返回目录流当前的读取位置 } } seekdir(dir,pos); //重新设置目录流目前的读取位置 printf("~~~~~~~~~~~~~~~~~~~~\n"); p = readdir(dir); printf("Ino = %ld len = %d type = %d filename = %s\n", p->d_ino, p->d_reclen, p->d_type, p->d_name); closedir(dir); //关闭目录文件 return 0;}
DIR的结构体定义如下:
struct __dirstream { void *__fd; /* `struct hurd_fd' pointer for descriptor. */ char *__data; int __entry_data; char *__ptr; int __entry_ptr; size_t __allocation; size_t __size; __libc_lock_define (, __lock)};typedef struct __dirstream DIR; //DIR的定义
DIR为目录流,类似于于FILE,这种文件包含了其他文件的名称和指向其他文件的文件描述符。通过opendir可以打开该目录流的接口。
opendir()用来打开参数 name 指定的目录,并返回 DIR*形态的目录流,和文件操作函数 open()类 似,接下来对目录的读取和搜索都要使用此返回值。函数失败则返回 NULL。 readdir()函数用来读取目录的信息,并返回一个结构体指针,该指针保存了目录的相关信息。有 错误发生或者读取到目录文件尾则返回 NULL。struct dirent { ino_t d_ino; /* inode number(此目录进入点的 inode) */ off_t d_off; /* offset to the next dirent(目录开头到进入点的位移) */ unsigned short d_reclen; /* length of this record(目录名的长度) */ unsigned char d_type; /* type of file(所指的文件类型) */ char d_name[256]; /* filename(文件名) */ };
所有的dirent信息构成的链表(顺序表)为DIR,存在一个指针定位当前所在的链表结点。
每次readdir会移动到链表的下一结点,readdir读取信息后,指针向后偏移,d_off指的是下一个结点的位置。经常用seekdir回到某个位置,而用telldir记录一个位置。 seekdir()函数用来设置目录流目前的读取位置,再调用 readdir()函数时,便可以从此新位置开始 读取。参数 offset 代表距离目录文件开头的偏移量。 telldir()函数用来返回目录流当前的读取位置。获取文件信息
可以通过 fstat 和 stat 函数获取文件信息,调用完毕后,文件信息被填充到结构体 struct stat 变量中,函数原型为:#include#include #include int stat(const char *file_name, struct stat *buf); //文件名 stat 结构体指针 int fstat(int fd, struct stat *buf); //文件描述符 stat 结构体指针
结构体 stat 的定义为:
struct stat { dev_t st_dev; /*如果是设备,返回设备表述符,否则为 0*/ ino_t st_ino; /* i 节点号 */ mode_t st_mode; /* 文件类型 */ 无符号短整型 nlink_t st_nlink; /* 链接数 */ uid_t st_uid; /* 属主 ID */ gid_t st_gid; /* 组 ID */ dev_t st_rdev; /* 设备类型*/ off_t st_size; /* 文件大小,字节表示 */ blksize_t st_blksize; /* 块大小*/ blkcnt_t st_blocks; /* 块数 */ time_t st_atime; /* 最后访问时间*/ time_t st_mtime; /* 最后修改时间*/ time_t st_ctime; /* 最后权限修改时间 */ };
对于结构体的成员 st_mode,有一组宏可以进行文件类型的判断:
S_ISLNK(mode) 判断是否是符号链接 S_ISREG(mode) 判断是否是普通文件 S_ISDIR(mode) 判断是否是目录 S_ISCHR(mode) 判断是否是字符型设备 S_ISBLK(mode) 判断是否是块设备 S_ISFIFO(mode) 判断是否是命名管道 S_ISSOCK(mode) 判断是否是套接字
案例:
#include#include int main() { struct stat buf; stat (“/etc/passwd”,&buf); printf(“/etc/passwd file size = %d \n”,buf.st_size);//st_size 可以得到文件大小 return 0;} //如果用 fstat 函数实现,如下: int fd = open (“/etc/passwd”,O_RDONLY); //先获得文件描述符fstat(fd, &buf);
案例:以树形结构的形式输出指定目录下面的所有文件
#include//自定义的头文件int printDir(char *path, int width){ DIR* dir; dir = opendir(path); ERROR_CHECK(dir, NULL, "opendir"); //自定义的宏 struct dirent *p; char buf[1024]={ 0}; while(p = readdir(dir)) { if (!strcmp(p->d_name, ".")||!strcmp(p->d_name, "..")) { continue; } printf("%*s%s\n",width,"",p->d_name); sprintf(buf,"%s%s%s",path,"/",p->d_name); if(4 == p->d_type) { printDir(buf, width+4); } } closedir(dir);}int main(int argc, char* argv[]){ ARGS_CHECK(argc, 2); //自定义的宏 puts(argv[1]); printDir(argv[1], 4); return 0;}
案例:传递任意一个目录路径,能够显示该目录的ls -l的效果
#includevoid printState(char* argv){ int ret; struct stat buf; ret = stat(argv,&buf); //传出参数 //打印文件类型 char file_type = '0'; if(S_ISLNK(buf.st_mode)) file_type = 'l'; else if( S_ISREG(buf.st_mode) ) file_type = '-'; else if( S_ISDIR(buf.st_mode) ) file_type = 'd'; else if( S_ISCHR(buf.st_mode) ) file_type = 'c'; else if( S_ISBLK(buf.st_mode) ) file_type = 'b'; else if( S_ISFIFO(buf.st_mode) ) file_type = 'p'; else if( S_ISSOCK(buf.st_mode) ) file_type = 's'; printf("%c ",file_type); //打印文件权限 char buffer[10]={ 0}; char tmp_buf[] = "rwxrwxrwx"; for(int i=0;i<9;i++) { if(buf.st_mode & (1<<(8-i))) { buffer[i] = tmp_buf[i]; } else { buffer[i] = '-'; } } printf("%s",buffer); printf("%ld %s %s %ld %s ",buf.st_nlink,getpwuid(buf.st_uid)->pw_name,getgrgid(buf.st_gid)->gr_name ,buf.st_size,ctime(&buf.st_mtime));}int printDir(char *path){ DIR* dir; dir = opendir(path); ERROR_CHECK(dir, NULL, "opendir"); struct dirent *p; char buf[1024]={ 0}; // char buf_t[1024]={0}; while(p = readdir(dir)) { if (!strcmp(p->d_name, ".")||!strcmp(p->d_name, "..")) { continue; } sprintf(buf,"%s%s%s",path,"/",p->d_name); char *argv = buf; printState(argv); printf("%s\n",p->d_name); // sprintf(buf,"%s%s%s",path,"/",p->d_name); if(4 == p->d_type) { printDir(buf); } } closedir(dir);}int main(int argc, char* argv[]){ ARGS_CHECK(argc, 2); printDir(argv[1]); return 0;}
转载地址:http://baxmb.baihongyu.com/