C語言:文件夾操作


這是很基礎的教程,我只是寫給自己看,作為一個學習筆記記錄一下,如果正在閱讀的你覺得簡單,請不要批評,可以關掉選擇離開

如何學好一門編程語言

  • 掌握基礎知識,為將來進一步學習打下良好的基礎。
  • 上機實踐,通過大量的例題學習怎么設計算法,培養解題思路。
  • 養成良好的編碼習慣,注釋一定要寫,要不然保你一周后自己寫的代碼都不認識了。

 

在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語言文件權限控制函數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM