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

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

UNIX 文件系統(tǒng)基本操作

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

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

引言

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

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

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

開始之前

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

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

讀取目錄條目

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

dirent.h 函數(shù),opendir()、readdir() 和 closedir(),它們正是您所需要的。這些函數(shù)的使用與用來對文件進行操作的 open/read/close 的習慣用法非常相似,但有一點除外:對于每個目錄條目,readdir() 函數(shù)一次返回一個指向特殊結構(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 )

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

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

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

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

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

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

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

獲取文件信息

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

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

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

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

st_ino——文件序列號

st_dev——文件設備號

st_nlink——文件連接計數(shù)

st_uid——所有者用戶 ID

st_gid——所有者組 ID

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

st_atime——最后的訪問時間

st_mtime——最后的修改時間

st_ctime——文件的創(chuàng)建時間

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

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

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

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

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

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

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

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

關于符號鏈接的說明

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

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

將其組合在一起

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

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

如清單 2 所示,這個簡單的演示應用程序中包含了各種 Header 文件。程序的開始塊中包含了大多數(shù)程序中使用的標準部分,并且后面的四項是在該程序中使用 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() 函數(shù)(開始于清單 3,結束于清單 6)讀取了指定的目錄,并顯示了每個條目的相關信息。opendir() 返回的 DIR 指針與 fopen() 返回的 FILE 指針類似,它是一個用于跟蹤目錄流的操作系統(tǒng)特定的對象,您應該忽略其具體內容。

清單 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;}

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

如果該條目是一個目錄,那么對這個目錄遞歸地調用 process_Directory(),并將其中所找到的條目數(shù)加到運行總數(shù)中。如果該條目是一個文件,那么顯示其名稱和字節(jié)數(shù)(可在 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 循環(huán)的底部,讀取另一個目錄條目并對其進行處理。如果您完成了對目錄條目的處理,那么關閉當前打開的目錄,并返回經(jīng)過處理的條目的數(shù)目。

清單 6. 讀取另一個條目

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

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

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

標簽: Unix系統(tǒng)
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
97精品国产| sm捆绑调教国产免费网站在线观看| 男女男精品网站| 国产精品亚洲一区二区在线观看| 国产一区二区三区黄网站 | 日韩美女精品| 99视频精品视频高清免费| 老司机精品视频网| 91福利精品在线观看| 亚洲天堂日韩在线| 欧美+日本+国产+在线a∨观看| 国产精品久久久久毛片大屁完整版 | 蜜乳av另类精品一区二区| 在线人成日本视频| 老鸭窝一区二区久久精品| 精品一区二区三区免费看| 精品一二三区| 久久精品亚洲欧美日韩精品中文字幕| 精品视频一二| 美女视频免费精品| 国产高清视频一区二区| 91成人精品在线| 免费精品国产的网站免费观看| 亚洲一区免费| 婷婷综合六月| 欧美/亚洲一区| 一区在线观看| 综合欧美精品| 久久大逼视频| 一区二区精彩视频| 久久精品xxxxx| 日韩av在线中文字幕| 欧美国产一级| 日韩在线麻豆| 免费不卡在线观看| 国产毛片久久久| 国产一区二区精品久| 99精品在线观看| 亚洲久久视频| 精品日韩一区| 国产精品7m凸凹视频分类| 蜜臀久久久久久久| 免费亚洲一区| 91综合视频| 久久爱www.| 久久久噜噜噜| 不卡在线一区二区| 国产色99精品9i| 免费精品国产的网站免费观看| 日精品一区二区三区| 精品美女视频| | 激情黄产视频在线免费观看| 欧美日韩国产传媒| 国产精品欧美一区二区三区不卡| 色婷婷精品视频| 日本色综合中文字幕| 日韩一区亚洲二区| 国产欧美在线观看免费| 欧美~级网站不卡| 国精品产品一区| 亚洲精品女人| 久久狠狠婷婷| 日韩精选在线| 久久国产生活片100| 欧美日韩国产欧| 日韩成人精品一区| 国产免费av国片精品草莓男男| 宅男在线一区| 999久久久亚洲| 日本精品黄色| 精品视频高潮| 日韩精彩视频在线观看| 午夜一级久久| 美女精品一区| 亚洲精品在线a| 麻豆91精品视频| 黑丝一区二区| 你懂的亚洲视频| 国产精品videossex久久发布| 一区二区三区网站| 日韩午夜视频在线| 日韩极品在线观看| 国产精品激情电影| 国产精品久久久久久妇女| 亚洲综合福利| 久久激情五月婷婷| 三级一区在线视频先锋| 亚洲综合二区| 日本欧美一区二区在线观看| 欧美亚洲色图校园春色| 国产极品嫩模在线观看91精品| 久久精品99国产精品| 精品国产免费人成网站| 极品av在线| 亚洲午夜黄色| 国产精品人人爽人人做我的可爱| 久久九九精品| 久久精品国语| 日韩一区二区三区精品视频第3页 日韩一区二区三区免费视频 | 91精品国产乱码久久久久久久 | 日韩在线播放一区二区| 亚洲一区二区免费在线观看| 欧美亚洲三区| 亚洲最新无码中文字幕久久| 日韩精品欧美激情一区二区| 亚洲综合欧美| 欧美激情91| 亚洲激情五月| 国产精品久久免费视频| 久久蜜桃av| 久久99蜜桃| 中文字幕av一区二区三区人| 激情久久中文字幕| 青草av.久久免费一区| 四季av一区二区凹凸精品| 国产精品毛片在线| 捆绑调教美女网站视频一区| 天堂资源在线亚洲| 国产伦精品一区二区三区视频| 精品香蕉视频| 亚洲一区二区三区无吗| 日韩不卡一区| 国产乱子精品一区二区在线观看 | 91成人在线网站| 日韩不卡免费视频| 蜜桃精品在线| 捆绑调教美女网站视频一区| 亚洲一区日本| 久久久9色精品国产一区二区三区| 美女精品一区| 亚洲91视频| 精品视频91| 久久女人天堂| 国产欧美激情| 国产欧美日韩影院| 亚洲欧美在线综合| 亚洲免费激情| 亚洲专区一区| 在线一区视频观看| 国产欧美日韩亚洲一区二区三区| 一区二区三区国产盗摄| av不卡在线| 国产视频一区在线观看一区免费| 久久国产影院| 欧美成人综合| 午夜久久黄色| 日韩一区精品视频| 久久不射网站| 99国产精品一区二区| 999精品在线| 午夜免费一区| 人人精品人人爱| 欧美日韩国产高清电影| 成人久久一区| 国产欧美二区| 国产精品亚洲人成在99www| 国产探花在线精品一区二区| 国产精品theporn| 国产精品成人3p一区二区三区| 国产精品a级| 在线亚洲人成| 一区二区三区视频免费观看 | 久久一区欧美| 精品久久国产一区| 日本欧美不卡| 中文字幕av一区二区三区人| 麻豆国产一区| 欧美日韩一二三四| 亚洲欧美日韩高清在线| 免费在线观看日韩欧美| 国产精品99久久免费| 成人片免费看| 国产99久久| 国产精品外国| 久久精品天堂| 夜夜嗨一区二区三区| 国产精品九九| 日韩网站在线| 91视频一区| 日韩高清在线一区| 国产综合欧美| 福利一区和二区| 欧美午夜三级| 日韩av一级| 欧美成人精品三级网站| 国产日本久久| 亚洲欧洲美洲国产香蕉| 亚洲手机在线| 成人片免费看| 国产成人免费av一区二区午夜| 亚洲精品进入| 日韩一区精品字幕| 中文一区在线| 香蕉国产精品| 极品日韩av| 91精品二区| jiujiure精品视频播放| 日韩电影免费网址| 国产人成精品一区二区三|