Linux目录操作

getcwd–获取当前工作目录

获取的路径是绝对路径。

1
char *getcwd(char *buf, size_t size);

但如果我们希望根据路径的实际长度来申请合适的空间,可以如下作:

1
char* cwd = getcwd(NULL,0);

chdir–改变当前工作目录

你可以填绝对路径,如果是相对路径就是基于当前路径的。

1
int chdir(const char *path);

mkdir–创建目录

1
int mkdir(const char *pathname, mode_t mode);

mode: 目录的权限位,会受文件创建掩码 umask 的影响,实际的权限为(mode & ~umask & 0777)返回值。

这很正常,不可能你一个没有写权限的用户,你执行这个函数就能让你创建有写权限的文件夹吧?这不合理。

rmdir–删除空目录

1
int rmdir(const char *path);

删除目录,因此后面我们实现如果递归删除目录和文件。

opendir–打开一个目录

1
DIR *opendir(const char *name);

打开成功会返回一个指向目录流的指针 DIR*。

closedir–关闭目录流

1
int closedir(DIR *dirp);

readdir–读目录流(核心)

1
struct dirent* readdir(DIR *dirp);

返回值是一个结构体,里面记录的信息是非常关键的,我们后面提供的三个核心小程序就是基于此操作的。

1
2
3
4
5
6
7
8
9
#include <sys/types.h>

struct dirent {
ino_t d_ino; // inode 编号
off_t d_off; // 下一条目在目录中的偏移
unsigned short d_reclen; // 结构体的长度
unsigned char d_type; // 文件类型
char d_name[256]; // 文件名
};

其中,常用以区分文件和文件夹的关键字就是 d_type,这是相当关键点。

1
2
3
4
5
6
7
8
DT_BLK:块设备。
DT_CHR:字符设备。
DT_DIR:目录。
DT_FIFO:命名管道(FIFO)。
DT_LNK:符号链接。
DT_REG:常规文件。
DT_SOCK:UNIX 域套接字。
DT_UNKNOWN:无法确定文件类型。

实例代码

实际上,上述接口并不难,最为核心的是 readdir 函数。而目录有关的操作就是递归遍历文件夹和文件,至于递归删除也就不在话下了。整个核心就是深度搜索,我们这里是前序遍历。

递归打印目录结构–青春版tree命令

递归复制目录

递归删除目录