C语言:文件夹操作
这是很基础的教程,我只是写给自己看,作为一个学习笔记记录一下,如果正在阅读的你觉得简单,请不要批评,可以关掉选择离开
如何学好一门编程语言
- 掌握基础知识,为将来进一步学习打下良好的基础。
- 上机实践,通过大量的例题学习怎么设计算法,培养解题思路。
- 养成良好的编码习惯,注释一定要写,要不然保你一周后自己写的代码都不认识了。
在Windows中的头文件为:#include <sys/types.h>
在Linux中的头文件为:#include <dirent.h>
opendir():打开目录函数
DIR * opendir(const char * name);
打开 name 指定的目录,并返回DIR*形态的目录流,和open()类似,接下来对目录的读取和搜索都要使用此返回值。
返回值:成功则返回DIR* 型态的目录流,打开失败则返回NULL。
错误代码:
- EACCESS 权限不足
- EMFILE 已达到进程可同时打开的文件数上限
- ENFILE 已达到系统可同时打开的文件数上限
- ENOTDIR 参数name 非真正的目录
- ENOENT 参数name 指定的目录不存在, 或是参数name 为一空字符串
- ENOMEM 核心内存不足
做一个有高修养的程序员,当我们打开文件夹时,最好做一下判断,是否打开成功
DIR *dir; // 目录流 dir = opendir("../folder"); if (dir==NULL){ printf("!Error: Cant't open dir.\n"); exit(1); }
readdir():读取目录
struct dirent * readdir(DIR * dir);
读取成功 返回 目录流dir 的下个目录进入点。有错误发生或读取到目录文件尾则返回NULL。
结构dirent 定义如下:
struct dirent { ino_t d_ino; //d_ino 此目录进入点的inode ff_t d_off; //d_off 目录文件开头至此目录进入点的位移 signed short int d_reclen; //d_reclen _name 的长度, 不包含NULL 字符 unsigned char d_type; //d_type d_name 所指的文件类型 d_name 文件名 har d_name[256]; };
案例:读取Q_and_A文件夹的文件
#include <stdio.h> #include <dirent.h> int main() { DIR *dir; // 目录流 struct dirent *ptr; dir = opendir("../R_and_A"); while ((ptr = readdir(dir)) != NULL) { printf("d_name : %s\n", ptr->d_name); } closedir(dir); } //d_name : . //d_name : .. //d_name : addr_to_digit.c //d_name : fen_and_he.c //d_name : read_license.c //d_name : struct_read_demo.c //d_name : struct_write_demo.c //d_name : test.txt
closedir():关闭目录流
int closedir(DIR *dir);
rewinddir():重设读取目录的位置为开头位置
void rewinddir(DIR *dir);
案例
#include <stdio.h> #include <dirent.h> int main() { DIR *dir; struct dirent *ptr; dir = opendir("../Q_and_A"); while ((ptr = readdir(dir)) != NULL) { printf("d_name : %s\n", ptr->d_name); } rewinddir(dir); printf("readdir again!\n"); while ((ptr = readdir(dir)) != NULL) { printf("d_name : %s\n", ptr->d_name); } closedir(dir); }
seekdir():设置下回读取目录的位置
telldir():获取目录流的当前 读取的 位置
void seekdir(DIR * dir, off_t offset);
案例
#include <stdio.h> #include <dirent.h> int main() { DIR *dir; struct dirent *ptr; int offset, offset_5, i = 0; dir = opendir("../R_and_A"); while ((ptr = readdir(dir)) != NULL) { offset = telldir(dir); // 获取目录流的读取位置 if (++i == 5) offset_5 = offset; printf("d_name : %s offset :%d \n", ptr->d_name, offset); } seekdir(dir, offset_5); // 设置读取目录流的位置 printf("Readdir again!\n"); while ((ptr = readdir(dir)) != NULL) { offset = telldir(dir); // 获取目录流的读取位置 printf("d_name : %s offset :%d\n", ptr->d_name, offset); } closedir(dir); }
getcwd():取得当前的工作目录
char * getcwd(char * buf, size_t size);
将当前的工作目录绝对路径复制到参数buf 所指的内存空间,参数size 为buf 的空间大小。
返回值:执行成功则将结果复制到参数buf 所指的内存空间,或是返回自动配置的字符串指针;失败返回NULL,错误代码存于errno。
注:
- 在调用此函数时,buf 所指的内存空间要足够大。若工作目录绝对路径的字符串长度超过参数size 大小,则返回NULL,errno 的值则为ERANGE。
- 倘若参数buf 为NULL,getcwd()会依参数size 的大小自动配置内存(使用malloc()),如果参数size 也为0,则getcwd()会依工作目录绝对路径的字符串程度来决定所配置的内存大小,进程可以在使用完次字符串后利用free()来释放此空间。
#include <stdio.h> #include <unistd.h> void main() { char buf[80]; getcwd(buf, sizeof(buf)); printf("当前工作目录为: %s\n", buf); // 当前工作目录为: /mnt/c/Users/anker/Desktop/C_learn/cmake-build-debug }
fchdir():改变当前工作目录
int fchdir(int fd);
将当前的工作目录改变成以参数fd 所指的文件描述词。
返回值:执行成功则返回 0,失败返回-1,errno 为错误代码。
#include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { int fd; fd = open("/tmp", O_RDONLY); fchdir(fd); printf("当前工作目录为: %s \n", getcwd(NULL, NULL)); // 当前工作目录为: /tmp close(fd); }
案例
读取文件夹下所有的文件
/* * Author: 凌逆战 | Never * Data: 2021/10/22 * Description: 读取文件夹下所有的文件 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> int readFileList(char *basePath, FILE *f) { DIR *dir; // 目录流 struct dirent *ptr; // 目录结构体指针 char base[1000]={0}; dir = opendir(basePath); // 打开目录 if (dir== NULL) { perror("Open dir error..."); exit(1); } // 读取目录 while ((ptr = readdir(dir)) != NULL) { if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) // 当前目录或父目录 continue; else if (ptr->d_type == 8) { // file printf("d_name:%s/%s\n", basePath, ptr->d_name); fprintf(f, "%s/%s\n", basePath, ptr->d_name); } else if (ptr->d_type == 10){ // link file printf("d_name:%s/%s\n", basePath, ptr->d_name); } else if (ptr->d_type == 4) { // dir strcpy(base, basePath); strcat(base, "/"); strcat(base, ptr->d_name); readFileList(base, f); } } closedir(dir); return 1; } int main(void) { char absolute_path[1000]={0}; FILE *f; f = fopen("../wavlist.txt", "w"); strcpy(absolute_path, "../folder_wav"); readFileList(absolute_path, f); fclose(f); return 0; }
参考
【C语言中文网】C语言文件权限控制函数