4. 目录操作函数
(1)mkdir和rmdir函数
头文件 |
#include<sys/types.h> #include<sys/stat.h> |
函数 |
int mkdir(const char* pathname, mode_t mode); int rmdir(const char* pathname); |
返回值 |
若成功则为0,若出错则为-1 |
功能 |
创建或删除目录 |
参数 |
mode:权限位(如S_IRWXU、0777) |
备注 |
(1)创建目录 ①创建一个新的空目录,.和..目录项是自动创建的。 ②创建目录时,至少指定一个执行权限位 (2)目录删除条件 ①该目录的链接计数为2(只包含.和..) ②无其它进程打开此目录 |
(2)opendir、readdir、rewinddir和closedir函数
头文件 |
#include<sys/types.h> #include<dirent.h> |
函数 |
(1)打开目录:DIR* opendir(const char* pathname);//成功返回目录指针,出错返回NULL。 (2)读取目录:struct direct* readdir(DIR* dp);//若在目录结尾或者出错返回NULL。 (3)把目录指针恢复到目录的起始位置:void rewinddir(DIR* dp); //成功返回0,出错返回-1。 (4)关闭目录:closedir(DIR* dp); //成功返回0,出错返回-1 |
参数 |
(1)dirent结构体 struct dirent{ ino_t d_ino; //inode number; char d_name[NAME_MAX+1]; //null-terminated filename } (2)DIR结构体 typedef struct __dirstream DIR; struct __dirstream { void *__fd; /* `struct hurd_fd' pointer for descriptor. */ char *__data; /* Directory block.*/ int __entry_data; /* Entry number `__data' corresponds to.*/ char *__ptr; /* Current pointer into the block. */ int __entry_ptr; /* Entry number `__ptr' corresponds to.*/ size_t __allocation; /* Space allocated for the block.*/ size_t __size; /* Total valid data in the block.*/ __libc_lock_define (, __lock) /* Mutex lock for this structure.*/ }; |
【编程实验】读取目录
//dir_read.c
#include <dirent.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> int main(int argc, char* argv[]) { if( argc < 2){ fprintf(stderr, "usage: %s dir\n", argv[0]); exit(1); } struct stat buff; if(lstat(argv[1], &buff) < 0){ perror("lstat error"); exit(1); } //判断是否是目录 if(!S_ISDIR(buff.st_mode)){ fprintf(stderr, "%s is not a directory!\n", argv[1]); exit(1); } //打开目录 DIR* dir = opendir(argv[1]); //读取目录内的信息 struct dirent* ent; while((ent = readdir(dir)) != NULL){ //打开文件(目录)名和i节点 printf("%-20s %10ld\n", ent->d_name, ent->d_ino); } closedir(dir); return 0; }
(3)chdir、fchdir、getcwd函数
头文件 |
#include<unistd.h> |
函数 |
(1)改变目录:(成功返回0,出错返回-1) int chdir(const char* pathname); //传入目录名 int fchdir(int fd); //己经打开的目录名 (2)获取当前工作目录(绝对路径) char* getcwd(char* buf, size_t size); //成功返回buf,出错返回NULL |
备注 |
当前工作目录是一个进程的属性,所以它只影响调用chdir的进程本身,而不影响其它进程。因此,不会影响进程的父进程shell的当前路径。 |
【编程实验】改变当前工作目录
//mchdir.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <memory.h> int main(int argc, char* argv[]) { if(argc < 2){ fprintf(stderr, "usage: %s dirpath\n", argv[0]); exit(1); } char buff[1024]; memset(buff, 0, sizeof(buff)); //获得当前工作目录 if(getcwd(buff, sizeof(buff)) != NULL){ printf("current dir: %s\n", buff); } //切换目录 if(chdir(argv[1]) < 0) { perror("chdir error"); exit(1); } //获得切换后的当前工作目录 memset(buff, 0, sizeof(buff)); if(getcwd(buff, sizeof(buff)) != NULL){ printf("current dir: %s\n", buff); } return 0; }
5. 设备特殊文件
(1)每个文件系统所在的存储设备都由其主、次设备号表示。设备号所用的数据类型是基本系统数据类型dev_t。主设备号标识设备驱动程序,有时编码为与其通信的外设板;次设备号标识特定的子设备。我们通常可以使用两个宏:major和minor来访问主、次设备号。
(2)系统中与每个文件名关联的st_dev值是文件系统的设备号,该文件系统包含了这一文件名以及与其对应的i节点。
(3)只有字符特殊文件和块设备特殊文件才有st_rdev值。此值包含实际设备的设备号。
【编程实验】查看设备文件的主次设备号
#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <memory.h> //显示特殊设备号(含主、次设备号) void out_dev(dev_t devno) { //生成主设备号和次设备号 int mj = major(devno); int mi = minor(devno); printf("%d, %d", mj, mi); } int main(int argc, char* argv[]) { if(argc < 2){ fprintf(stderr, "usage: %s files", argv[0]); exit(1); } struct stat buff; int i = 0; for(i=1; i<argc; i++){ memset(&buff, 0, sizeof(buff)); if(lstat(argv[i], &buff) < 0){ perror("lstat error"); continue; } printf("%-20s", argv[i]); //判断是否是字符设备或块设备文件 if(S_ISCHR(buff.st_mode) || S_ISBLK(buff.st_mode)){ printf("device file: "); //输出特殊设备设备号(包括主、次设备号); out_dev(buff.st_rdev); } printf(" on: "); //输出所有文件都具有的设备号(含主、次设备号) out_dev(buff.st_dev); printf("\n"); } return 0; }