C語言目錄操作



目錄的操作不論是在嵌入式還是應用軟件編程都是必不可少的,不同的開發語言可能略有不同,本章節主要是討論在Linux系統下目錄的一系列操作,以我的個人經驗,創建目錄和列出目錄中的文件這兩個功能用得最多。

一、獲取當前工作目錄

在shell中我們可以直接輸入命令pwd來顯示當前的工作目錄,在C程序中調用getcwd函數可以獲取當前的工作目錄。函數聲明:

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

getcwd函數把當前工作目錄存入buf中,如果目錄名超出了參數size長度,函數返回NULL,如果成功,返回buf。例如:

  char strpwd[301];
  memset(strpwd,0,sizeof(strpwd))
  getcwd(strpwd,300);
  printf("當前目錄是:%s\n",strpwd);

二、切換工作目錄

函數聲明:

int chdir(const char *path);

就像我們在shell中使用cd命令切換目錄一樣,在C程序中使用chdir函數來改變工作目錄。

返回值:0-切換成功;非0-失敗。

三、目錄的創建和刪除

在shell中可以通過mkdir/rmdir命令來創建/刪除目錄,C程序中用mkdir/rmdir函數來創建/刪除目錄。

創建目錄函數的聲明:

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

mode的含義將按open系統調用的O_CREAT選項中的有關定義設置,當然,它還要服從umask的設置況,是不是看不明白?那先固定填0755,注意,0不要省略哦,它表示八進制。 例如:

mkdir("/tmp/aaa",0755);   // 創建/tmp/aaa目錄

刪除目錄函數的聲明:

int rmdir(const char *pathname);

四、獲取目錄中的文件列表

在實際開發中,文件是存放在目錄中的,在處理文件之前,必須先知道目錄中有哪些文件,所以要獲取目錄中的文件列表。涉及到的庫函數如下:

1、包含頭文件

#include <dirent.h>

2、相關的庫函數

打開目錄的函數opendir的聲明:

DIR *opendir(const char *pathname);

讀取目錄的函數readdir的聲明:

struct dirent *readdir(DIR *dirp);

關閉目錄的函數closedir的聲明:

int closedir(DIR *dirp);

3、數據結構

1)目錄指針DIR

DIR *目錄指針名;

2)struct dirent結構體

每調用一次readdir函數會返回一個struct dirent的地址,存放了本次讀取到的內容,它的原理與fgets函數讀取文件相同。

struct dirent
{
   long d_ino;                    // inode number 索引節點號
   off_t d_off;                   // offset to this dirent 在目錄文件中的偏移 
   unsigned short d_reclen;     // length of this d_name 文件名長 
   unsigned char d_type;         // the type of d_name 文件類型
   char d_name [NAME_MAX+1];    // file name文件名,最長255字符
};

我們只需要關注結構體的d_type和d_name成員,其它的不必關心。

d_name文件名或目錄名。

d_type描述了文件的類型,有多種取值,最重要的是8和4,8-常規文件(A regular file);4-目錄(A directory),其它的暫時不關心。

4、讀取目錄

示例(book123.cpp)

/*
 * 程序名:book123.c,此程序用於演示讀取目錄下的文件名信息
 * 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <dirent.h>

int main(int argc,char *argv[])
{
  if (argc != 2)  { printf("請指定目錄名。\n"); return -1; }

  DIR *dir;   // 定義目錄指針

  // 打開/tmp目錄
  if ( (dir=opendir(argv[1])) == 0 ) return -1;

  // 用於存放從目錄中讀取到的文件和目錄信息
  struct dirent *stdinfo;

  while (1)
  {
    // 讀取一條記錄並顯示到屏幕
    if ((stdinfo=readdir(dir)) == 0) break;

    printf("name=%s,type=%d\n",stdinfo->d_name,stdinfo->d_type);
  }

  closedir(dir);   // 關閉目錄指針
}

運行效果

在這里插入圖片描述

五、應用經驗

在實際開發中,對目錄的操作並不會像book123.c那樣簡單。

實際需求是這樣的,文件存放在某目錄中,該目錄下還會有多級子目錄,程序員想要的是列出該目錄及其子目錄下全部的文件名。

例如存在/home/wucz/tmp目錄,其子目錄結構和文件如下:

在這里插入圖片描述

示例(book124.c)

/*
 * 程序名:book124.c,此程序用於演示讀取目錄及其子目錄下全部的文件信息
 * 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <dirent.h>

// 列出目錄及子目錄下的文件
int ReadDir(const char *strpathname);

int main(int argc,char *argv[])
{
  if (argc != 2)  { printf("請指定目錄名。\n"); return -1; }

  // 列出目錄及子目錄下的文件
  ReadDir(argv[1]);
}

// 列出目錄及子目錄下的文件
int ReadDir(const char *strpathname)
{
  DIR *dir;   // 定義目錄指針
  char strchdpath[256];  // 子目錄的全路徑

  if ( (dir=opendir(strpathname)) == 0 ) return -1; // 打開目錄

  struct dirent *stdinfo; // 用於存放從目錄讀取到的文件和目錄信息

  while (1)
  {
    if ((stdinfo=readdir(dir)) == 0) break;   // 讀取一記錄

    if (strncmp(stdinfo->d_name,".",1)==0) continue;  // 以.開始的文件不讀

    if (stdinfo->d_type==8)    // 如果是文件,顯示出來
      printf("name=%s/%s\n",strpathname,stdinfo->d_name);

    if (stdinfo->d_type==4)   // 如果是目錄,再調用一次ReadDir
    {
      sprintf(strchdpath,"%s/%s",strpathname,stdinfo->d_name);
      ReadDir(strchdpath);
    }
  }

  closedir(dir);   // 關閉目錄指針
}

運行效果

在這里插入圖片描述

這才是程序員想要的結果。

在某些C語言的教材里,有遞歸函數這個概念,在我的教程里,沒有講這個概念,實際上,book124.c的ReadDir函數就是一個遞歸函數,在ReadDir函數中調用了自身。

六、課后作業

編寫示例程序,把本章節介紹的知識點全部演示一遍,用程序演示可以加深您的理解和映象。

七、版權聲明

C語言技術網原創文章,轉載請說明文章的來源、作者和原文的鏈接。
來源:C語言技術網(www.freecplus.net)
作者:碼農有道

如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!


免責聲明!

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



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