跳轉到內容

C 程式設計/POSIX 參考/dirent.h

來自華夏公益教科書,開放的書籍,為開放的世界

dirent.hC POSIX 庫 中用於 C 程式語言 的標頭檔案,包含用於簡化目錄遍歷的構造。該函式不是 C 標準的一部分,但被認為是“偽標準”,通常在平臺之間可移植。

名稱 註釋
int closedir(DIR* dirp) 關閉由 dirp 引用的目錄流。返回後,dirp 可能不再指向可訪問的 DIR 型別物件。如果使用檔案描述符來實現 DIR 型別,則該檔案描述符將被關閉。成功完成時,closedir() 返回 0。否則,返回 -1 並且 errno 被設定為指示錯誤。

errno 錯誤:EBADF 表示 dirp 不引用開啟的目錄流,EINTR 表示該函式被訊號中斷。

DIR* opendir(const char* dirname) 開啟一個與 dirname 指定的目錄對應的目錄流。目錄流定位在第一個條目處。如果 DIR 型別是使用檔案描述符實現的,應用程式將只能開啟總共不超過 OPEN_MAX 個檔案和目錄。成功完成時,opendir() 返回一個指向 DIR 型別物件的指標。否則,返回空指標並且 errno 被設定為指示錯誤。

errno 錯誤:EACCES 表示對 dirname 的路徑字首的元件拒絕搜尋許可權,或者對 dirname 拒絕讀取許可權。ELOOP 表示在解析路徑時遇到太多符號連結。ENAMETOOLONG 表示 dirname 引數的長度超過 PATH_MAX,或者路徑名元件超過 NAME_MAX。ENOENT 表示 dirname 的一個元件不是現有目錄的名稱,或者 dirname 是一個空字串。ENOTDIR 表示 dirname 的一個元件不是目錄。EMFILE 表示呼叫程序中當前打開了 OPEN_MAX 個檔案描述符。ENAMETOOLONG 表示符號連結的路徑名解析產生了一箇中間結果,其長度超過 PATH_MAX。ENFILE 表示系統中當前打開了太多檔案。

struct dirent* readdir(DIR* dirp) 返回一個指向表示由引數 dirp 指定的目錄流中當前位置處的目錄條目的結構的指標,並將目錄流定位在下一個條目處。到達目錄流末尾時,它返回一個空指標。如果點或點點的條目存在,將為點返回一個條目,為點點返回一個條目;否則將不返回它們。遇到錯誤時,將返回空指標,並設定 errno 以指示錯誤。遇到目錄末尾時,將返回空指標,並且 errno 不改變。

返回值指向的記憶體位置由庫管理,並在後續對 readdir 的呼叫中可能會改變。它不應由使用者釋放

errno 錯誤:EOVERFLOW 表示要返回的結構中的某個值不能被正確表示。EBADF 表示 dirp 不引用開啟的目錄流。ENOENT 表示目錄流的當前位置無效。

int readdir_r(DIR* dirp, struct dirent* entry, struct dirent** result) entry 初始化為表示 dirp 中當前位置處的目錄條目,將指向該結構的指標儲存在 result 引用的位置,並將目錄流定位在下一個條目處。entry 指向的儲存將足夠大,可以容納一個 dirent,其 char d_name 成員的陣列至少包含 NAME_MAX 加一個元素。成功返回時,在 *result 中返回的指標將具有與引數 entry 相同的值。到達目錄流末尾時,該指標將具有 NULL 值。

errno 錯誤:EBADF 表示 dirp 不引用開啟的目錄流。

void rewinddir(DIR* dirp) 將 dirp 引用的目錄流的位置重置到目錄的開頭。它還使目錄流引用對應目錄的當前狀態,就像呼叫 opendir() 一樣。如果 dirp 不引用目錄流,則效果未定義。
void seekdir(DIR* dirp, long int loc) 將 dirp 指定的目錄流上下次 readdir() 操作的位置設定為 loc 指定的位置。loc 的值應該是從之前的 telldir() 呼叫返回的。新位置恢復到與執行 telldir() 時關聯的目錄流的位置。如果 loc 的值不是從之前的 telldir() 呼叫獲得的,或者在 telldir() 呼叫和 seekdir() 呼叫之間發生了 rewinddir() 呼叫,則後續呼叫 readdir() 的結果是不確定的。
long int telldir(DIR* dirp) 獲取與 dirp 指定的目錄流關聯的當前位置。如果目錄流上的最近一次操作是 seekdir(),則從 telldir() 返回的目錄位置與為 seekdir() 提供的 loc 引數相同。成功完成時,telldir() 返回指定目錄流的當前位置。

成員常量

[編輯 | 編輯原始碼]

stdio.h 標頭檔案中定義的常量包括

名稱 註釋
NAME_MAX (或 FILENAME_MAX) char 陣列 d_name 的最大長度。

成員型別

[編輯 | 編輯原始碼]

dirent.h 標頭檔案中定義的資料型別包括

  • DIR - 表示目錄流的結構。它的結構沒有被 POSIX 定義,通常對使用者來說是不透明的。
  • struct dirent - 具有以下成員的結構
  • ino_t d_ino - 檔案序列號
  • char d_name[] - 條目的名稱(不會超過 NAME_MAX 的大小)
  • 此外,struct dirent 可能會包含以下成員,具體取決於平臺
  • off_t d_off - 檔案偏移量
  • unsigned short int d_reclen - dirent 記錄的長度
  • unsigned short int d_namlen - 名稱的長度
  • unsigned int d_type - 檔案型別

標準化

[編輯 | 編輯原始碼]

dirent.h 包含在大多數 PC 架構的 C/C++ 庫中。

已知 dirent.h 包含在以下編譯器中

  • Turbo C++ (DOS)
  • GCC (跨平臺)
  • MinGW (GCC 的 Microsoft Windows 版本)
  • Borland C++ Builder (Microsoft Windows)

Microsoft Visual C++ **不** 包含 dirent.h

dirent.h 使用的簡短示例如下

/**************************************************************
 * A simpler and shorter implementation of ls(1)
 * ls(1) is very similar to the DIR command on DOS and Windows.
 **************************************************************/
#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) 
{
  struct dirent *entry;
  DIR *dp;

  dp = opendir(path);
  if (dp == NULL) 
  {
    perror("opendir");
    return -1;
  }

  while((entry = readdir(dp)))
    puts(entry->d_name);

  closedir(dp);
  return 0;
}

int main(int argc, char **argv) {
  int counter = 1;

  if (argc == 1)
	listdir(".");

  while (++counter <= argc) {
    printf("\nListing %s...\n", argv[counter-1]);
    listdir(argv[counter-1]);
  }

  return 0;
}

將原始碼放在一個檔案 (listdir.c) 中,並像這樣編譯 (在 Linux shell 中)

gcc listdir.c -o listdir

或者像這樣

gcc listdir.c -o listdir.exe

在 Windows/DOS 環境中。

現在,要執行 (在 Linux shell 中) 鍵入

 ./listdir

或者鍵入

 listdir.exe

在 Windows/DOS shell 中。

參考文獻

[編輯 | 編輯原始碼]
華夏公益教科書