1. 程式人生 > >Linux 下獲取目錄a下檔案b的操作

Linux 下獲取目錄a下檔案b的操作



最近在看Linux下檔案操作相關章節,遇到了這麼幾個結構體,被搞的暈乎乎的,今日有空,仔細研究了一下,受益匪淺。

DIR結構體類似於FILE,是一個內部結構,以下幾個函式用這個內部結構儲存當前正在被讀取的目錄的有關資訊(摘自《UNIX環境高階程式設計(第二版)》)。函式 DIR *opendir(const char *pathname),即開啟檔案目錄,返回的就是指向DIR結構體的指標,而該指標由以下幾個函式使用:

首先說說DIR這一結構體,以下為DIR結構體的定義:

struct __dirstream    {     void *__fd;     char *__data;
    int __entry_data;     char *__ptr;     int __entry_ptr;     size_t __allocation;     size_t __size;     __libc_lock_define (, __lock)    }; typedef struct __dirstream DIR;

DIR結構體類似於FILE,是一個內部結構,以下幾個函式用這個內部結構儲存當前正在被讀取的目錄的有關資訊(摘自)。函式 DIR*opendir(const char *pathname),即開啟檔案目錄,返回的就是指向DIR結構體的指標,而該指標由以下幾個函式使用

:

struct dirent *readdir(DIR *dp); void rewinddir(DIR *dp); int closedir(DIR *dp); long telldir(DIR *dp); void seekdir(DIR *dp,long loc);

關於DIR結構,我們知道這麼多就可以了,沒必要去再去研究他的結構成員。

接著是dirent結構體,首先我們要弄清楚目錄檔案(directory file)的概念:這種檔案包含了其他檔案的名字以及指向與這些檔案有關的資訊的指標(摘自)。從定義能夠看出,dirent不僅僅指向目錄,還指向目錄中的具體檔案,

readdir函式同樣也讀取目錄下的檔案,這就是證據。以下為dirent結構體的定義:

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 (null-terminated) 檔名,最長255字元 */ }

從上述定義也能夠看出來,dirent結構體儲存的關於檔案的資訊很少,所以dirent同樣也是起著一個索引的作用,如果想獲得類似ls -l那種效果的檔案資訊,必須要靠stat函數了。

通過readdir函式讀取到的檔名儲存在結構體direntd_name成員中,而函式

int stat(const char *file_name, struct stat*buf);

的作用就是獲取檔名為d_name的檔案的詳細資訊,儲存在stat結構體中。以下為stat結構體的定義:

struct stat {         mode_t     st_mode;       //檔案訪問許可權         ino_t      st_ino;       //索引節點號         dev_t      st_dev;        //檔案使用的裝置號         dev_t      st_rdev;       //裝置檔案的裝置號         nlink_t    st_nlink;      //檔案的硬連線數         uid_t      st_uid;        //所有者使用者識別號         gid_t      st_gid;        //組識別號         off_t      st_size;       //以位元組為單位的檔案容量         time_t     st_atime;      //最後一次訪問該檔案的時間         time_t     st_mtime;      //最後一次修改該檔案的時間         time_t     st_ctime;      //最後一次改變該檔案狀態的時間         blksize_t st_blksize;    //包含該檔案的磁碟塊的大小         blkcnt_t   st_blocks;     //該檔案所佔的磁碟塊       };

這個記錄的資訊就很詳細了吧,呵呵。

後,總結一下,想要獲取某目錄下(比如a目下)b檔案的詳細資訊,我們應該怎樣做?

首先,我們使用opendir函式開啟目錄a,返回指向目錄aDIR結構體c

接著,我們呼叫readdir( c)函式讀取目錄a下所有檔案(包括目錄),返回指向目錄a下所有檔案dirent結構體d

然後,我們遍歷d,呼叫statd->name,stat *e)來獲取每個檔案的詳細資訊,儲存在stat結構體e中。

總體就是這樣一種逐步細化的過程,在這一過程中,三種結構體扮演著不同的角色。