zl程序教程

您现在的位置是:首页 >  IT要闻

当前栏目

C语言:文件夹操作

2023-02-18 16:40:17 时间

这是很基础的教程,我只是写给自己看,作为一个学习笔记记录一下,如果正在阅读的你觉得简单,请不要批评,可以关掉选择离开

如何学好一门编程语言

  • 掌握基础知识,为将来进一步学习打下良好的基础。
  • 上机实践,通过大量的例题学习怎么设计算法,培养解题思路。
  • 养成良好的编码习惯,注释一定要写,要不然保你一周后自己写的代码都不认识了。

 

在Windows中的头文件为:#include <sys/types.h>   

在Linux中的头文件为:#include <dirent.h>

opendir():打开目录函数

DIR * opendir(const char * name);

  打开 name 指定的目录,并返回DIR*形态的目录流,和open()类似,接下来对目录的读取和搜索都要使用此返回值。

返回值:成功则返回DIR* 型态的目录流,打开失败则返回NULL。

错误代码:

  1. EACCESS 权限不足
  2. EMFILE 已达到进程可同时打开的文件数上限
  3. ENFILE 已达到系统可同时打开的文件数上限
  4. ENOTDIR 参数name 非真正的目录
  5. ENOENT 参数name 指定的目录不存在, 或是参数name 为一空字符串
  6. 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);
}
View Code

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);
}
View Code

getcwd():取得当前的工作目录

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

  将当前的工作目录绝对路径复制到参数buf 所指的内存空间,参数size 为buf 的空间大小。

返回值:执行成功则将结果复制到参数buf 所指的内存空间,或是返回自动配置的字符串指针;失败返回NULL,错误代码存于errno。

注:

  1. 在调用此函数时,buf 所指的内存空间要足够大。若工作目录绝对路径的字符串长度超过参数size 大小,则返回NULL,errno 的值则为ERANGE。
  2. 倘若参数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语言文件权限控制函数