初学C 语⾔之⽬录操作
⽂章⽬录
主要说明linux下,创建⽬录和列出⽬录中的⽂件两个功能, 使⽤场景最多
⼀. 获取当前⽬录
char *getcwd(char *buf, size_t size)
⼆.切换⽬录
int chdir(const char *path);
三. ⽬录的创建和删除
1. 创建⽬录 int mkdir(const char *pathname, mode_t mode);
1. mode : 就是⽬录的权限相关的, 可以固定为00755
2. 删除⽬录 int rmdir(const char *pathname);
四. 获取⽬录中的⽂件列表
4.1 包含头⽂件
#include <dirent.h>
4.2 包含的库函数
1. 打开⽬录的库函数 DIR *opendir(const char *pathname);
2. 读取⽬录的库函数: struct dirent *readdir(DIR *dirp);
3. 关闭⽬录的函数: int closedir(DIR, *dirp);
4.3 数据结构
DIR是⽬录指针,就像⽂件操作时的⽂件指针⼀样
调⽤⼀次readdir返回结构体struct dirent的指针, 只管⽤就⾏了,不⽤管怎么实现的.存放的是本次读取到的⽂件信息, 就像操作⽂件时调⽤⼀次fgets 时⼀样,不同的是,fgets 返回字符串, readdir 返回结构体.
struct dirent{
long d_ino; //inode number 索引节点号
off_t d_off; // offset to this dirent 在⽬录中的偏移
unsigned short d_name; // length of this d_name ⽂件名长
unsigned char d_type; // the type of d_name ⽂件类型
char d_name[NAME_MAX+a]; // file name ⽂件名,最长255字符
}
我们只关⼼d_type和d_name成员, 其它不关⼼
d_name: 是⽂件名,或⽬录名
d_type: 描述了⽂件的类型, 有多种取值, 常⽤的是8和4, 8-常规⽂件(A regular file), 4-⽬录⽂件(A directory), 其它的暂时不⽤管上码明所有#include  <stdio.h>#include  <stdlib.h>#include  <string.h>
1
2
3
#include  <string.h>#include  <dirent.h>    // readdir 需要包含的头⽂件#include  <unistd.h>int  ReadDir (const  char  *strpathname );  // 以递归⽅式获取⽬录中及其⼦⽬录中的⽂件,并打印出来int  MKDIR (const  char  *pathname );  // 以递归⽅式创建⽬录int  main (){    char  strcwd [301];    // 获取当前⽬录    memset (strcwd , 0, sizeof (strcwd ));    getcwd (strcwd , sizeof (strcwd ));    printf ("=%s=\n", strcwd );    // 切换⽬录⾄'/home'    chdir ("/home");    memset (strcwd , 0, sizeof (strcwd ));    getcwd (strcwd , sizeof (strcwd ));    printf ("=%s=\n", strcwd );    // 创建⽬录和删除⽬录    mkdir ("/home/hello/c", 00755);    rmdir ("/home/hello/c");    // 以递归⽅式获取⽬录中的⽂件    ReadDir ("/home/hello");    // 以递归⽅式创建⽬录    MKDIR ("/home/hello/testc/test2c/test3c");    return  0;}int  MKDIR (const  char  *pathname ){    char  strPathName [301];    int  ii =0;    for (ii =1; ii <strlen (pathname ); ii ++){        if (pathname [ii ]!='/') continue ;        memset (strPathName , 0, sizeof (strPathName ));        strncpy (strPathName , pathname , 1);        // 判断⽬录是否存在, 若存在,则返回0,不存在返回-1, 后⾯有讲到.        if (access (strPathName ,F_OK )==0) continue ;        if (mkdir (strPathName , 00755)!=0) return  -1;    }    return  0;}int  ReadDir (const  char  *strpathname ){    // 获取⽬录中的⽂件    DIR *dir ;  // 定义⽬录指针    char  strchdpath [256];  // ⼦⽬录的全路径    if  ((dir =(
opendir (strpathname ))) ==0 ){        printf ("打开⽬录失败");        return  -1;    }    struct  dirent *stdinfo ;  // 定义了⼀个结构指针, ⽤于存放从⽬录中读取到的⽂件和⽬录>的信息    while (1){        stdinfo =readdir (dir );        if (stdinfo ==0) break ;  //  结束了,就跳出循环        if  (strncmp (stdinfo ->d_name , ".", 1)==0) continue ; // 过滤以.开始的⽂件        // 若是常规⽂件, 就打印出来
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
五. 补充⼀哈
5.1 access 库函数
功能: ⽤于判断当前操作系统⽤户对⽂件或⽬录的存取权限包含头⽂件: #include <unistd.h>
申明⽅式: int access(const char *pathname, int mode);
- pathname ⽂件名或⽬录名, 可以是当前⽬录的⽂件或⽬录,也可以是全路径(实际开发中,建议使⽤全路径)
- mode 需要判断的存取权限,在头⽂件<unistd.h>中的预定义如下:- #define R_OK 4 // R_OK只判断是否有读权限
- #define W_OK 2 // W_OK只判断是否有写权限
- #define X_OK 1 // X_OK判断是否有执⾏权限
- #define F_OK 0 // F_OK只判断是否存在
返回值: 当pathname 满⾜mode时, 返回0, 不满⾜返回-1.
实际开发中, 主要⽤判断⽂件是否存在.
5.2 stat 库函数
5.2.1 stat 结构体 ⽤于存放⽂件的状态信息
5.2.2 stat 库函数
包含的头⽂件:
sys/types.h sys/stat.h unistd.h
申明:
int stat(const char* path, struct stat *buf)
stat函数获取path 指定⽂件或⽬录的信息, 并将 信息保存到结构体buf中,执⾏成功0, 失败返回-1.        // 若是常规⽂件, 就打印出来        if  (stdinfo ->d_type ==8){            printf ("⽂件名=%s, ⽂件类型=%d\n", stdinfo ->d_name , stdinfo ->d_type );        }        //若是⽬录⽂件, 就递归        if  (stdinfo ->d_type ==4){            sprintf (strchdpath , "%s/%s", strpathname , stdinfo ->d_name );            ReadDir (strchdpath );        }    }    closedir (dir ); //关闭⽬录指针    return  0;}
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82struct  stat { dev_t st_dev ; //device ⽂件的设备编号  ino_t st_ino ; //inode ⽂件的i-node  mode_t st_mode ; //protection ⽂件的类型和存取的权限, 开发中常⽤,取值很多, nlink_t st_nlink ; //numbers of hard links 连到该⽂件的硬连接数⽬, 刚建⽴的⽂件为1. uid_t st_uid ; // user ID of owner ⽂件所有者的⽤户识别码 gid_t st_gid ; //gourp ID of owner ⽂件所有者的组识别码 dev_t st_rdev ; //若此⽂件为装置设备⽂件, 则为其设备编号 off_t st_size ; // total size, in bytes, ⽂件⼤⼩,以字节计算, 开发中, 常⽤. unsigned  long  st_blksize ;  //blocksize of filesystem I/O, ⽂件系统的IO 缓冲区⼤⼩ unsigned  long  st_blocks ;  //numbers of blocks allocated 占⽤⽂件区块的个数, 每⼀区域⼤⼩为512字节  time_t st_atime ; //time of last access  ⽂件最近⼀次被存取或执⾏的时间,⼀般只有在⽤mknod, utime, read,
write, tructate 时改变 time_t st_mtime ; //time of last modification ⽂件最后⼀次被修改的时间,⼀般只有在⽤mknod, utime, write 时改变, 实际开发中, 常⽤ time_t st_ctime ; // time of last change i-node  最后⼀次被更改的时间, 此参数会在⽂件所有者, 组, 权限被更改时更新.  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
调⽤时, 要记得带个⽬录或⽂件的参数, 否则直接打印不存在. , 因为调⽤时, 在函数内部都是argv[1], 表⽰是第⼆个参数.
5.2.3 utime 库函数
功能: ⽤于修改⽂件的存取时间和更改时间包含头⽂件: #include <utime.h>
申明: int utime(const char *filename, const struct utimbuf *times);
说明: utime()⽤来修改filename⽂件所属的inode存取时间. 如果参数times为空指针(NULL),则该⽂件的存取时间和更改时间全部会设为当前时间,结构体 utimbuf定义如下:
struct utimbuf {
time_t actime;
time_t modtime;
};5.2.4 rename 函数
⽤于重命名⽂件或⽬录, 相当于操作系统的mv命令, 实际开发过程中, 极少重命名⽬录, 重命名⽂件经常⽤到.
int rename(const char *oldpath, const char *newpath);
oldpath, ⽂件或⽬录的原名
newapth,⽂件或⽬录的新的名称
成功返回0, 失败返回-1
实际开发中, 经常会向⼀个⽂件中写⼊数据, 别⼈来读取数据, 但是, 当你正在写⼊时, 别⼈同时读取这个⽂件, 就会造成读到数据不完整. 解决办法: 就是在写⼊fopen("/", "w")时, 在⽂件名后加个.tmp, 即fopen("/p", "w"), 当⽂件close 后, 再使⽤
rename("/p", "/"), 把.tmp删除即可. 完美解决!!
5.2.5 remove 函数
删除⽂件或⽬录#include  <stdio.h>#include  <sys/stat.h>#include  <unistd.h>int  main (int  argc , char  *argv []){    if  (access (argv [1], F_OK ) !=0){        printf ("⽂件或⽬录%s 不存在\n", argv [1]);        return  -1;    }    struct  stat ststat ;    if (stat (argv [1], &ststat )!=0) return  -1;    if  (S_ISREG (ststat .st_mode )) printf ("%s 是⼀个⽂件\n", argv [1]);    if  (S_ISDIR (ststat .st_mode )) printf ("%s 是⼀个⽬录\n", argv [1]);    printf ("filename=%s, mtime=%ld, size=%d\n", argv [1], ststat .st_mtime , ststat .st_size );}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18c语言struct头文件
19
20
21
22struct  utimbuf stut ;strtotime ("2021-05-01 10:10:10", &stut .actime );strtotime ("2021-05-01 10:10:10", &stut .modtime );utime (filename , &stut );
1
2
3
4

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。