<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                需要用到的頭文件為: #include <sys/types.h> #include <dirent.h> #打開文件夾 DIR *opendir(const char *name); DIR *fdopendir(int fd); opendir()函數打開一個指定路徑name的文件夾關聯的流,并將該流以執行結果的方式返回給調用者。在默認情況下,該流指向文件夾下的第一個目錄。 fdopendir()函數與opendir()是相同的,只是該函數接收的方式是文件描述符fd。fd可以通過執行函數int dirfd(DIR *dirp);獲得。需要注意的是將fd做為參數傳遞給fdopendir()之后,則該fd就不要在程序中的其它地方使用了。 以上兩個函數正常執行時都會返回與文件夾相關聯的流;否則返回NULL,錯誤的原因可以從errno中獲得。 #遍歷文件夾下的內容 #####讀取文件夾下的子文件(夾) struct dirent *readdir(DIR *dirp); NO Thread-Safe int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); Thread-Safe 執行readdir()函數將返回文件夾流dirp中的下一個條目,即文件夾下的子目錄,重復執行時將會逐一返回文件夾下所有的子目錄;一旦返回NULL則表示已經把所有的子目錄都遍歷過了或者出現了錯誤(可以通過errno查看)。 返回的結果是這樣的一個結構體: struct dirent { ino_t d_ino; /* 在文件系統中的inode number */ off_t d_seekoff; /* 與文件夾流的位置指針操作相關 */ unsigned short d_reclen; /* 本記錄的數據長度 */ unsigned char d_type; /* 當前遍歷子項的文件類型:文件、文件夾、link、socket等 */ char d_name[256]; /* 當前遍歷子項的文件名 */ }; 以上結構體出自 man ,在不同系統上會有各自不同的差別。 在上面的結構體中,文件名d_name的限制長度256是包括字符串終止符’\0’的,所以在OS中,文件夾的命名最大字符數是255個。(在Mac中嘗試是無法輸入第256個字符的) 結構體中的d_type用于標識當前的文件夾類型,支持的類型有: DT_BLK This is a block device. DT_CHR This is a character device. DT_DIR 文件夾 This is a directory. DT_FIFO This is a named pipe (FIFO). DT_LNK 符號鏈接文件 This is a symbolic link. DT_REG 文件 This is a regular file. DT_SOCK SOCKET鏈接 This is a UNIX domain socket. DT_UNKNOWN The file type is unknown. readdir_r()是readdir()的可重入實現版本,功能是一致的,但readdir_r()是線程安全的。 執行readdir_r()時遍歷得到的子目錄數據會存放在第二個參數entry中,第三個參數result指針指向子目錄的entry,且函數返回值返回0。當遍歷到文件夾結束的位置時,返回值仍返回0,但第三個參數result指針指向NULL。當函數執行錯誤時,則返回一個大于0的數字(即EBADF)。 #####文件夾位置指針的操作 long telldir(DIR *dirp); void seekdir(DIR *dirp, long loc); void rewinddir(DIR *dirp); DIR也是流的一種,對其進行讀操作時也有位置指針的概念及操作。 telldir()可以獲取當前的位置指針位置。返回值表示當前遍歷的子目錄是當前文件夾下的第幾個目錄(第0個是”.”當前目錄,第1個是”..”上一級目錄,所以從第2個開始計數。) seekdir()可以操作位置指針跳轉到指定的子目錄序號loc。 rewinddir()可以將位置指針恢復到流的起始位置。 #####遍歷、過濾文件夾下的子文件(夾) int scandir(const char *dirp, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)); int scandirat(int dirfd, const char *dirp, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)); scandir()是遍歷文件夾的另一種方式。本函數支持自定義遍歷的過濾條件及結果排序,封閉了遍歷的實現,執行后直接提供合法的目錄信息,但該信息也只是目錄名稱而已。函數的返回結果是合法的子目錄的個數;當函數執行出現錯誤時則返回-1且可以通過errno去錯誤詳情。 dirp指定要遍歷的文件夾路徑。 namelist用于指向遍歷結果。可以看出該指針指向一個二維的字符數組,該二維數組存儲著文件夾下的所有合法的文件名。 *filter是一個函數指針,該函數有一個參數const struct dirent *是指在遍歷過程中所遍歷到的每一個子目錄dirent,filter可以根據dirent的類型、名稱等信息來判定當前的dirent是否為合法的子目錄,合法則函數返回0,則該子目錄的名稱會被存儲在namelist中;否則返回非0,則該子目錄被過濾掉。 *compar也是一個函數指針,該函數的兩個參數都是const struct dirent *用于決定兩個子目錄在namelist中的順序。 C的庫中也默認提供了兩個文件名稱排序的方法: int alphasort(const struct dirent **a, const struct dirent **b); int versionsort(const struct dirent **a, const struct dirent **b); alphasort()的實現是把dirent的名稱用strcoll()進行比較,排序的結果是按ASCII編碼的值由小到大排序。 versionsort()的實現是把dirent的名稱strverscmp()進行比較,排序的結果是也按ASCII編碼的值由小到大排序,不同的是支持對名稱中按數字序號的排序。舉個例子對比alphasort()與versionsort()的不同: alphasort: pc1 pc10 pc2 … pc9 versionsort: pc1 pc2 … pc9 pc10 很明顯,versionsort()的排序結果更符合普通人的閱讀習慣。 scandirat()是scandirat()的擴展函數,主要區別就在于第一個參數dirfd與第二個參數dirp。 如果dirp是一個絕對路徑的字符串,則函數無視參數dirfd,功能與scandir()一致。 如果dirp是一個相對路徑的字符串,且參數dirfd的值是AT_FDCWD (#include <fcntl.h>),則表示從應用程序當前的工作路徑拼接上dirp的相對路徑所組成的絕對路徑下去遍歷;當dirfd值不為AT_FDCWD時而是一個代替文件夾的file descriptor(參考dirfd(DIR*))時,則遍歷的文件夾路徑即為dirfd所指向的文件夾再拼接上dirp的相對路徑所組成的絕對路徑。 下面的示例代碼演示了readdir readdir_r scandir三種方式遍歷文件夾的實現。 > #include <stdio.h> > #include <errno.h> > #include <unistd.h> > #include <stdlib.h> > #include <string.h> > #include <dirent.h> > #include <sys/stat.h> > static void printFileType(int type) { > // 子文件 類型 > printf("type:%x ", type); > switch (type) { > case DT_FIFO: > printf(" fifo."); > break; > case DT_CHR: > printf(" character."); > break; > case DT_DIR: > printf(" directory."); > break; > case DT_BLK: > printf(" block."); > break; > case DT_REG: > printf(" regular file."); > break; > case DT_LNK: > printf(" link."); > break; > case DT_SOCK: > printf(" socket."); > break; > case DT_WHT: > printf(" WHT."); > break; > case DT_UNKNOWN: > default: > printf(" unknown."); > break; > } > } > static void print_dir(const char * dirPath, DIR * dir) { > struct dirent * file; > // 遍歷文件夾下的內容 > while ((file = readdir(dir)) != NULL) { > printf("dir position=%ld ", telldir(dir)); > // 排隊掉"."(當前目錄)和".."(上一級),無用的信息 > if(strcmp(file->d_name, ".") == 0 > || strcmp(file->d_name, "..") == 0) { > printf("ignore:%s \n", file->d_name); > continue; > } > // 子文件 文件名 > printf("sub file:%20s ", file->d_name); > // 子文件 inode節點信息 > printf("inode:%llx ", file->d_ino); > printf("off:%llx ", file->d_seekoff); // 和流的位置指針相關 > printFileType(file->d_type); > printf("\n"); > } > } > static void print_dir_r(DIR * dir) { > struct dirent entry; > struct dirent * result = &entry; > while(1){ > printf("dir position=%ld ", telldir(dir)); > int res = readdir_r(dir, result, &result); > if (res == 0){ > if (result == NULL) { > break; > } else { > printf("sub file:%20s ", entry.d_name); > printFileType(entry.d_type); > printf("\n"); > } > } else { > printf("readdir_r() fail:%s \n", strerror(errno)); > break; > } > } > printf("\n"); > } > /**過濾掉的“.”與".."*/ > static int filterDot(const struct dirent * dir) { > if (strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name, "..") == 0) { > // 過濾掉 "."和".." > return 0; > } else { > return 1; > } > } > static void print_scan_dir(const char * path) { > // 指向字符的二維數組,該數組存儲著文件夾下的合法子目錄名 > struct dirent **namelist; > int n; > > n = scandir(path, &namelist, filterDot, alphasort); > printf("after scandir, entry num:%d \n", n); > if (n < 0) { > perror("scandir"); > } else { > int idx = 0; > while (idx !=n) { > printf("idx=%d suf file:%20s \n", idx, namelist[idx]->d_name); > // 釋放掉namelist > free(namelist[idx]); > idx ++; > } > // 釋放掉namelist > free(namelist); > } > } > int main(int argc, char ** argv) { > // 指定的一個文件夾路徑 > char * dirPath = "/Users/sodino/workspace/xcode/CString/CString/test"; > > // 打開文件夾 > DIR* dir = opendir(dirPath); > print_dir(dirPath, dir); > > // 重置文件夾位置指針至流的起始位置,以便后續再次遍歷 > rewinddir(dir); > > printf("\n\ndo rewinddir() and go on to list entry(s)\n\n"); > print_dir_r(dir); > > // 重置文件夾位置指針至流的起始位置,以便后續再次遍歷 > rewinddir(dir); > > printf("\n\n do scandir() \n"); > print_scan_dir(dirPath); > > // 關閉 > closedir(dir); > return EXIT_SUCCESS; > } 效果如下圖: directory directory #文件夾關閉 int closedir(DIR *dirp); closedir()將關閉一個與文件夾相關聯的流。執行本函數后,dirp將不可再被使用。 #刪除文件夾 int rmdir(const char *pathname); 刪除指定路徑下的文件夾。如果刪除成功,則返回0;否則返回-1,并可通過errno查看失敗原因。 #創建文件夾 int mkdir(const char *pathname, mode_t mode); int mkdirat(int dirfd, const char *pathname, mode_t mode); mkdir()函數用于創建文件夾,參數pathname指定要創建的文件夾的絕對路徑。參數mode用于限定文件夾的文件權限(組)。該mode將會OR操作后合成struct stat中的st_mode(詳情)。文件權限(組)的mode具體定義見下文的File Mode Bits(懶得翻譯了,直接上英文)。所設置的文件權限(組)可以通過命令ls -l -a查看。 如果函數正常執行并創建文件夾成功,則返回0;否則返回-1并且可以通過errno查看錯誤詳情。 擴展:直接mkdir(path, S_IRWXU| S_IRWXG| S_IRWXO),可生成的文件夾權限組是drwxr-xr-x而不是drwxrwxrwx? 原因是:mkdir()函數中指定的參數mode值會和當前程序的umask處理一下,具體處理為mode & ~unmask & 0777才是最終的文件夾權限組。查看當前用戶或程序的umask可以在命令行終端上輸入命令umask可看。一般用戶的umask值為0022。 mkdirat()函數是mkdir()的擴展,參數中dirfd與pathname的用法跟 scandir()與scandirat()的用法是一致的,這里就不重復說明了。 #####File Mode Bits:##### S_IRWXU read, write, execute/search by owner S_IRUSR read permission, owner S_IWUSR write permission, owner S_IXUSR execute/search permission, owner S_IRWXG read, write, execute/search by group S_IRGRP read permission, group S_IWGRP write permission, group S_IXGRP execute/search permission, group S_IRWXO read, write, execute/search by others S_IROTH read permission, others S_IWOTH write permission, others S_IXOTH execute/search permission, others S_ISUID set-user-ID on execution S_ISGID set-group-ID on execution S_ISVTX on directories, restricted deletion flag The bits defined by S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH, S_ISUID, S_ISGID and S_ISVTX are unique. S_IRWXU is the bitwise OR of S_IRUSR, S_IWUSR and S_IXUSR. S_IRWXG is the bitwise OR of S_IRGRP, S_IWGRP and S_IXGRP. S_IRWXO is the bitwise OR of S_IROTH, S_IWOTH and S_IXOTH. [原文地址](http://sodino.com/2015/03/09/c-directory-io/) http://sodino.com/2015/03/09/c-directory-io/
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看