日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

UNIX 文件系統基本操作

瀏覽:38日期:2024-06-12 15:22:24

本文示例源代碼或素材下載

引言

Unix® 中任何事物都是文件 的觀點意味著,您將始終會與文件和目錄打交道,無論您開發的是何種類型的應用程序。任何事物都存儲為文件,從數據到配置文件、甚至是設備,在對 UNIX 編程經過幾個小時的學習之后,stdio.h 系統 Header 中的函數將能夠為您提供很好的幫助。

一個時常困擾 UNIX 編程新手的問題是,如何瀏覽一個目錄,并對其中的文件、目錄和符號鏈接進行相應的處理。如何能夠獲取它們的列表,以及如何能夠確定它們究竟是什么?

請繼續閱讀本文,以學習如何使用 dirent.h 函數系列 (opendir()/readdir()/closedir()) 來讀取目錄中的條目,以及使用 stat() 函數來確定這些條目所對應的內容。

開始之前

本文中的示例代碼(請參見下載)使用 C/C++ 開發工具 (CDT) 在 Eclipse 3.1 中編寫,readdir_demo 項目是一個托管的 Make 項目,該項目通過使用 CDT 程序生成規則構建。您在這個項目中找不到 Makefile,但是它們非常簡單,如果需要在 Eclipse 之外編譯這些代碼,您可以很容易地生成相應的 Makefile。

如果您還沒有嘗試使用 Eclipse,那么您真的應該試一試。它是一個非常好的集成開發環境 (IDE),并且隨著發行版本的不斷更新,它變得更加完善。它來自于生命力頑強的 EMacS 以及基于 Makefile 的開發工具。請參閱本文結尾處的參考資料部分,其中提供了一些很好的 Eclipse 文章的鏈接。

讀取目錄條目

對于一個給定路徑的目錄,應該如何讀取其中的條目呢?您無法像操作文件那樣打開目錄(使用 open() 或 fopen() 函數),并且即便可以這樣做,所得到的數據可能是您正在使用的文件系統的專用格式,而對于不十分熟悉的程序員來說,直接訪問這些數據將使情況變得更糟。

dirent.h 函數,opendir()、readdir() 和 closedir(),它們正是您所需要的。這些函數的使用與用來對文件進行操作的 open/read/close 的習慣用法非常相似,但有一點除外:對于每個目錄條目,readdir() 函數一次返回一個指向特殊結構(struct dirent 類型)的指針。通常,對目錄進行瀏覽類似于清單 1 中所示的偽代碼。

清單 1. 讀取目錄中的內容

dir = opendir( "some/path/name" )entry = readdir( dir )while entry is not NULL:do_something_with( entry )entry = readdir( dir )closedir( dir )

在出現問題時,opendir() 和 readdir() 函數都會返回 NULL,并且將設置全局變量 errno 的值,以指出所出現的錯誤。如果 readdir() 返回 NULL,并且 errno 為 0(有時也稱為 EOK 或 ENOERROR),則表示沒有其他的目錄條目。

有一點需要注意,每個目錄都包含“.(對該目錄的引用)和“..(對該目錄的父目錄的引用)條目。根據您所進行的操作,可能需要忽略對這些條目的處理。

請注意,readdir() 不是線程安全的,因為所返回的結構是存儲在函數庫中的一個靜態變量。大多數現代的 Unix 系統都具有線程安全的 readdir_r(),如果您正在編寫線程代碼,可以使用這個函數作為替代。

struct dirent 中包含了哪些內容呢?

POSIX 1003.1 標準僅僅為 struct dirent 定義了一個必需的條目,即 char 數組 d_name。這是用標準的以 NULL 結尾的字符串表示的該條目的名稱。這個結構中任何其他內容都是特定于您的 UNIX 系統的。

的確如此,struct dirent 中其他所有內容 都是不可移植的。嚴格滿足一致性的系統不應該在其中包含任何其他的內容。如果您編寫了使用額外結構成員的代碼,那么您必須將其標記為不可移植的,并且包含一個完成相同任務的替換代碼路徑,如果您認為這樣做特別友好的話。

例如,許多 Unix 包含一個 d_type 成員和一些附加常量,這樣一來,您無需額外的 stat() 調用就可以檢查目錄條目的類型。除了減少另外的系統調用之外,這種不可移植的擴展還減少了從文件系統獲取更多元數據的開銷非常高的訪問操作。眾所周知,在大多數 UNIX 上,stat() 函數的執行速度非常慢。

獲取文件信息

除了獲取目錄中條目的名稱之外,您可能還需要一些附加信息,以確定下一步要進行的操作。至少,僅根據目錄條目的名稱,您無法辨別文件條目。

stat() 函數會將特定文件的相關信息填入 struct stat 結構中,如果您獲得的是文件描述符而不是文件名,那么作為替代,您可以使用 fstat() 函數。如果您想能夠檢測出符號鏈接,那么可以對文件名使用 lstat()。

與 readdir() 返回的 struct dirent 不同,struct stat 具有相當多的標準的、必需的成員:

st_mode——文件權限(用戶、其他用戶、組)和標志

st_ino——文件序列號

st_dev——文件設備號

st_nlink——文件連接計數

st_uid——所有者用戶 ID

st_gid——所有者組 ID

st_size——以字節表示的文件大小(針對普通文件)

st_atime——最后的訪問時間

st_mtime——最后的修改時間

st_ctime——文件的創建時間

對 st_mode 成員使用 S_*() 宏,這樣就可以找出您所處理的目錄條目的類型:

S_ISBLK(mode)——是否為塊特殊文件?(通常是某種基于塊的設備)

S_ISCHR(mode)——是否為字符特殊文件?(通常是某種基于字符的設備)

S_ISDIR(mode)——是否為目錄?

S_ISFIFO(mode)——是否為管道或 FIFO 特殊文件?

S_ISLNK(mode)——是否為符號鏈接?

S_ISREG(mode)——是否為普通文件?

眾所周知,在大多數文件系統上,stat() 函數的執行速度非常慢,所以如果您打算在將來再次使用該信息,可能需要對其進行緩存。

關于符號鏈接的說明

通常,您并不關心符號鏈接。如果對符號鏈接調用 stat(),那么您將獲取該鏈接所指向的文件的相關信息。這和用戶的體驗是一致的,因為控制與該文件交互的是目標文件的權限,而不是符號鏈接本身。

有些應用程序,如 ls 和備份程序,需要能夠顯示鏈接文件本身的相關信息,例如它所指向的文件。當您使用 lstat() 來代替 stat() 時,以及當您出于特定的目的而需要獲取符號鏈接本身的相關信息,而不是直接與其鏈接的文件打交道時,情況也是這樣的。

將其組合在一起

既然已經學習了如何使用 readdir() 和 stat() 來查找目錄中的條目,那么讓我們來看看演示這些函數的一些實際代碼。

這里所介紹的代碼將瀏覽命令行中指定的一個或多個目錄,并顯示在該目錄中找到的每個條目的相關信息。當它找到另一個目錄時,它會對該目錄進行同樣的處理。對于符號鏈接,將顯示其目標文件,并且還將顯示普通文件的大小。將忽略特殊文件。

如清單 2 所示,這個簡單的演示應用程序中包含了各種 Header 文件。程序的開始塊中包含了大多數程序中使用的標準部分,并且后面的四項是在該程序中使用 readdir() 和 stat() 所必需的。

清單 2. Header 和常量

#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <limits.h>#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>#include <unistd.h>

process_Directory() 函數(開始于清單 3,結束于清單 6)讀取了指定的目錄,并顯示了每個條目的相關信息。opendir() 返回的 DIR 指針與 fopen() 返回的 FILE 指針類似,它是一個用于跟蹤目錄流的操作系統特定的對象,您應該忽略其具體內容。

清單 3. 處理一個目錄

unsigned process_directory( char *theDir ){DIR *dir = NULL;struct dirent entry;struct dirent *entryPtr = NULL;int retval = 0;unsigned count = 0;char pathName[PATH_MAX + 1];/* Open the given directory, if you can. */ dir = opendir( theDir );if( dir == NULL ) {printf( "Error opening %s: %s", theDir, strerror( errno ) );return 0;}

在打開了指定的目錄之后,調用 readdir_r()(請參見清單 4)以獲取關于第一個條目的信息,隨后每次調用 readdir_r() 都將返回下一個條目,直到到達了目錄末尾,并且 entryPtr 被設置為 NULL。這里還使用了 strncmp() 來檢查“.和“..條目,以便略過它們。如果不略過它們,您將永遠都在處理類似“theDir/./././././././././.等這樣的目錄。

清單 4. 讀取一個目錄條目

retval = readdir_r( dir, &entry, &entryPtr );while( entryPtr != NULL ) {struct stat entryInfo;if( ( strncmp( entry.d_name, ".", PATH_MAX ) == 0 ) ||( strncmp( entry.d_name, "..", PATH_MAX ) == 0 ) ) {/* Short-circuit the . and .. entrIEs. */retval = readdir_r( dir, &entry, &entryPtr );continue;}

既然已經得到了目錄的條目名稱,那么您需要構造一個更加完整的路徑(請參見清單 5),然后調用 lstat() 以獲取該條目的相關信息。因為符號鏈接需要特殊的處理,所以這里使用了 lstat() 函數。您可以使用 readlink() 函數找到其目標文件。

如果該條目是一個目錄,那么對這個目錄遞歸地調用 process_Directory(),并將其中所找到的條目數加到運行總數中。如果該條目是一個文件,那么顯示其名稱和字節數(可在 struct stat 的 st_size 成員中找到)。

清單 5. 處理條目

(void)strncpy( pathName, theDir, PATH_MAX );(void)strncat( pathName, "/", PATH_MAX );(void)strncat( pathName, entry.d_name, PATH_MAX );if( lstat( pathName, &entryInfo ) == 0 ) {/* stat() succeeded, let's party */count++;if( S_ISDIR( entryInfo.st_mode ) ) {/* directory */printf( "processing %s/n", pathName );count += process_directory( pathName );} else if( S_ISREG( entryInfo.st_mode ) ) {/* regular file */printf( "t%s has %lld bytesn",pathName, (long long)entryInfo.st_size );} else if( S_ISLNK( entryInfo.st_mode ) ) {/* symbolic link */char targetName[PATH_MAX + 1];if( readlink( pathName, targetName, PATH_MAX ) != -1 ) {printf( "t%s -> %sn", pathName, targetName );} else {printf( "t%s -> (invalid symbolic link!)n",pathName );}}} else {printf( "Error statting %s: %sn", pathName, strerror(errno ) );}

在 while 循環的底部,讀取另一個目錄條目并對其進行處理。如果您完成了對目錄條目的處理,那么關閉當前打開的目錄,并返回經過處理的條目的數目。

清單 6. 讀取另一個條目

retval = readdir_r( dir, &entry, &entryPtr );}/* Close the Directory and return the number of entrIEs. */(void)closedir( dir );return count;}

最后,清單 7 顯示了該程序的 main() 函數,它只是對命令行中傳遞的每個參數調用了 process_directory() 函數。一個真正的程序應該具有使用方法消息,并且在用戶沒有指定任何參數時,提供某種形式的反饋信息,但我把這項內容作為練習留給讀者。

清單 7. 主線

/* readdir_demo main()** Run through the specified directories, and pass them* to process_directory().*/int main( int argc, char **argv ){int idx = 0;unsigned count = 0;for( idx = 1; idx < argc; idx++ ) {count += process_directory( argv[idx] );}return EXIT_SUCCESS;}

這就是整個程序。盡管包含了較多的文件,但處理目錄條目并不是十分困難。

結束語

使用 readdir() 和 stat() 函數瀏覽目錄中的條目并確定對其進行的額外處理,是非常簡單的,在您需要列舉目錄中的內容時,也可能會使用到這種處理方法。它是一種很實用的方法,但是對于一些沒有經驗的 Unix 開發人員來說,卻難以掌握。本文的目的是降低其難度,使得 UNIX 開發人員能夠充分利用這些有價值的函數。

標簽: Unix系統
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久国产精品亚洲77777| 日韩一区二区三区四区五区| 免费在线观看日韩欧美| 91精品国产成人观看| 电影91久久久| 蜜桃久久久久| 国产欧美亚洲一区| 久久亚洲美女| 成人精品久久| 高清av一区| 7777精品| 91成人超碰| 激情婷婷亚洲| 欧美日韩尤物久久| 日韩毛片网站| 日韩激情av在线| 久久xxx视频| 日韩中文在线电影| 亚洲免费激情| 欧美日韩 国产精品| 国产在线观看www| 激情久久中文字幕| 日本在线视频一区二区| 国产精品久久乐| 国产麻豆久久| 日韩视频一区二区三区在线播放免费观看| 久久亚洲欧洲| 国产精品激情| 女同性一区二区三区人了人一| 亚洲五月综合| 精品国产中文字幕第一页| 欧美丝袜一区| 久久精品72免费观看| 久久精品播放| 欧美精品影院| 亚洲电影在线一区二区三区| 日韩在线黄色| 欧美色图一区| 国产欧美一区二区色老头| 久久精品影视| 九一精品国产| 国产伦精品一区二区三区在线播放| 成人日韩精品| 国产精品va视频| 日韩影院免费视频| 国产在线不卡一区二区三区| 老鸭窝亚洲一区二区三区| 欧美国产专区| 亚洲精品少妇| 亚洲va在线| 日韩va亚洲va欧美va久久| 久久精品国产99久久| 国产三级一区| 日韩视频二区| 中文字幕系列一区| 日本午夜精品一区二区三区电影 | 日产欧产美韩系列久久99| 欧美韩日一区| 国产剧情在线观看一区| 亚洲精品在线观看91| 国产一区日韩| 久久国产精品免费精品3p | 亚洲色图国产| 欧美+日本+国产+在线a∨观看| 丝袜国产日韩另类美女| av在线最新| 日韩动漫一区| 一区免费在线| 日韩在线短视频| 国产一区二区色噜噜| 国产免费久久| 亚洲毛片一区| 日韩影院在线观看| 播放一区二区| 欧美亚洲日本精品| 精品伊人久久| 国产伦精品一区二区三区视频| 免费在线欧美视频| 国产亚洲午夜| 欧美日韩免费观看视频| 麻豆视频一区| 国产精品久久久久久久久免费高清| 日韩一区精品视频| 久久亚洲欧洲| 99pao成人国产永久免费视频| 亚洲国内欧美| 久久精品一区二区不卡| 亚洲综合在线电影| 日韩亚洲一区在线| av高清一区| 91精品国产91久久久久久黑人| 91精品xxx在线观看| 欧美激情另类| 成人精品国产亚洲| 国产一区 二区| 久久国产生活片100| 亚洲精品日韩久久| 日韩中文av| 亚洲制服欧美另类| 热久久久久久| 国产精品美女久久久久久不卡| 国产精品欧美在线观看| 久久麻豆视频| 97精品在线| 色一区二区三区| 国产一区观看| 日韩专区在线视频| 日韩精品a在线观看91| 日韩精品导航| 国产精品男女| 国内揄拍国内精品久久| 中文字幕在线免费观看视频| 欧美日韩一二三四| 最新日韩av| 免费观看在线综合色| 久久国内精品自在自线400部| 欧美激情一区| 色综合狠狠操| 99国产精品99久久久久久粉嫩| 久久亚洲二区| 国产精品一页| 天堂av在线| 精品在线播放| 亚洲精品少妇| 国产精品久久| 国产九九精品| 日韩在线观看不卡| 日韩精品一二三| 久久99影视| 日韩一区二区三区在线免费观看| 欧美精品一二| 久久国产人妖系列| 日韩精品诱惑一区?区三区| 亚洲精品电影| 久久精品xxxxx| 日韩欧美精品| 亚洲精品福利| 亚洲伦乱视频| 蜜臀av国产精品久久久久 | 樱桃视频成人在线观看| 91九色精品| 国产精品一区毛片| 欧美午夜精彩| 国产精品多人| 欧美成人午夜| 欧美黄色一区| 西西人体一区二区| 国产一区2区| 欧美综合国产| 毛片在线网站| 日韩精品欧美精品| 欧美日韩亚洲在线观看| 国产日韩精品视频一区二区三区| 精品99在线| 亚洲男人在线| 色网在线免费观看| 日韩高清二区| 好看不卡的中文字幕| 免费在线欧美黄色| 中文无码日韩欧| 91精品一区二区三区综合| 日韩av不卡一区二区| 国产综合精品一区| 欧美激情综合| 亚洲欧洲专区| 九色精品91| 日韩毛片视频| 国产精品白丝av嫩草影院| 99精品在线免费在线观看| 国产精品久久久久久久久免费高清 | 国产精品一区高清| 欧美日韩精品免费观看视频完整| 国产精品www.| 亚州国产精品| 99久久激情| 麻豆mv在线观看| 日韩激情中文字幕| 亚洲先锋成人| 国产成人在线中文字幕| 欧美日韩精品一区二区三区视频 | 美女精品一区| 91精品在线观看国产| 精品视频一区二区三区四区五区 | 在线成人直播| 日韩成人精品一区二区| 91亚洲精品在看在线观看高清| 亚洲欧美日韩视频二区| 丝袜美腿一区| 精品国产免费人成网站| 欧美黄页在线免费观看| 欧美伊人久久| 日韩在线视频一区二区三区| 男女性色大片免费观看一区二区 | 色综合www| 日本在线啊啊| 老牛影视精品| 日韩专区精品| 久久精品国产精品亚洲毛片| 国产精品草草| 麻豆精品av|