1.Linux文件系統(tǒng) Linux支持多種文件系統(tǒng),如ext,、ext2,、minix,、iso9660、msdos,、fat,、vfat、nfs等,。在這些具體文件系統(tǒng)的上層,,Linux提供了虛擬文件系統(tǒng)(VFS)來統(tǒng)一它們的行為,虛擬文件系統(tǒng)為不同的文件系統(tǒng)與內(nèi)核的通信提供了一致的接口,。下圖給出了Linux中文件系統(tǒng)的關系: 在Linux平臺下對文件編程可以使用兩類函數(shù):(1)Linux操作系統(tǒng)文件API,;(2)C語言I/O庫函數(shù)。 前者依賴于Linux系統(tǒng)調(diào)用,,后者實際上與操作系統(tǒng)是獨立的,,因為在任何操作系統(tǒng)下,使用C語言I/O庫函數(shù)操作文件的方法都是相同的,。本章將對這兩種方法進行實例講解,。 2.Linux文件API Linux的文件操作API涉及到創(chuàng)建、打開,、讀寫和關閉文件,。 創(chuàng)建
參數(shù)mode指定新建文件的存取權限,它同umask一起決定文件的最終權限(mode&umask),,其中umask代表了文件在創(chuàng)建時需要去掉的一些存取權限,。umask可通過系統(tǒng)調(diào)用umask()來改變:
該調(diào)用將umask設置為newmask,然后返回舊的umask,,它只影響讀,、寫和執(zhí)行權限,。 打開
open函數(shù)有兩個形式,,其中pathname是我們要打開的文件名(包含路徑名稱,缺省是認為在當前路徑下面),,flags可以去下面的一個值或者是幾個值的組合:
O_RDONLY,、O_WRONLY,、O_RDWR三個標志只能使用任意的一個。 如果使用了O_CREATE標志,,則使用的函數(shù)是int open(const char *pathname,int flags,mode_t mode); 這個時候我們還要指定mode標志,,用來表示文件的訪問權限。mode可以是以下情況的組合:
除了可以通過上述宏進行“或”邏輯產(chǎn)生標志以外,,我們也可以自己用數(shù)字來表示,,Linux總共用5個數(shù)字來表示文件的各種權限:第一位表示設置用戶ID;第二位表示設置組ID,;第三位表示用戶自己的權限位,;第四位表示組的權限;最后一位表示其他人的權限,。每個數(shù)字可以取1(執(zhí)行權限),、2(寫權限)、4(讀權限),、0(無)或者是這些值的和,。例如,要創(chuàng)建一個用戶可讀,、可寫,、可執(zhí)行,但是組沒有權限,,其他人可以讀,、可以執(zhí)行的文件,并設置用戶ID位,。那么,,我們應該使用的模式是1(設置用戶ID)、0(不設置組ID),、7(1+2+4,,讀、寫,、執(zhí)行),、0(沒有權限)、5(1+4,,讀,、執(zhí)行)即10705:
上述語句等價于:
如果文件打開成功,open函數(shù)會返回一個文件描述符,,以后對該文件的所有操作就可以通過對這個文件描述符進行操作來實現(xiàn),。 讀寫 在文件打開以后,我們才可對文件進行讀寫了,,Linux中提供文件讀寫的系統(tǒng)調(diào)用是read,、write函數(shù):
其中參數(shù)buf為指向緩沖區(qū)的指針,length為緩沖區(qū)的大小(以字節(jié)為單位),。函數(shù)read()實現(xiàn)從文件描述符fd所指定的文件中讀取length個字節(jié)到buf所指向的緩沖區(qū)中,,返回值為實際讀取的字節(jié)數(shù)。函數(shù)write實現(xiàn)將把length個字節(jié)從buf指向的緩沖區(qū)中寫到文件描述符fd所指向的文件中,,返回值為實際寫入的字節(jié)數(shù),。 以O_CREAT為標志的open實際上實現(xiàn)了文件創(chuàng)建的功能,因此,,下面的函數(shù)等同creat()函數(shù):
定位 對于隨機文件,,我們可以隨機的指定位置讀寫,使用如下函數(shù)進行定位:
lseek()將文件讀寫指針相對whence移動offset個字節(jié),。操作成功時,,返回文件指針相對于文件頭的位置。參數(shù)whence可使用下述值: SEEK_SET:相對文件開頭 SEEK_CUR:相對文件讀寫指針的當前位置 SEEK_END:相對文件末尾 offset可取負值,,例如下述調(diào)用可將文件指針相對當前位置向前移動5個字節(jié):
由于lseek函數(shù)的返回值為文件指針相對于文件頭的位置,,因此下列調(diào)用的返回值就是文件的長度:
關閉 當我們操作完成以后,我們要關閉文件了,,只要調(diào)用close就可以了,,其中fd是我們要關閉的文件描述符:
例程:編寫一個程序,在當前目錄下創(chuàng)建用戶可讀寫文件“hello.txt”,,在其中寫入“Hello, software weekly”,,關閉該文件。再次打開該文件,,讀取其中的內(nèi)容并輸出在屏幕上,。
編譯并運行,執(zhí)行結果如下圖: 3.C語言庫函數(shù) C庫函數(shù)的文件操作實際上是獨立于具體的操作系統(tǒng)平臺的,,不管是在DOS,、Windows、Linux還是在VxWorks中都是這些函數(shù): 創(chuàng)建和打開
fopen()實現(xiàn)打開指定文件filename,,其中的mode為打開模式,,C語言中支持的打開模式如下表:
其中b用于區(qū)分二進制文件和文本文件,,這一點在DOS,、Windows系統(tǒng)中是有區(qū)分的,但Linux不區(qū)分二進制文件和文本文件,。 讀寫 C庫函數(shù)支持以字符,、字符串等為單位,支持按照某中格式進行文件的讀寫,,這一組函數(shù)為:
fread()實現(xiàn)從流stream中讀取加n個字段,,每個字段為size字節(jié),并將讀取的字段放入ptr所指的字符數(shù)組中,,返回實際已讀取的字段數(shù),。在讀取的字段數(shù)小于num時,可能是在函數(shù)調(diào)用時出現(xiàn)錯誤,,也可能是讀到文件的結尾,。所以要通過調(diào)用feof()和ferror()來判斷。 write()實現(xiàn)從緩沖區(qū)ptr所指的數(shù)組中把n個字段寫到流stream中,,每個字段長為size個字節(jié),,返回實際寫入的字段數(shù)。 另外,,C庫函數(shù)還提供了讀寫過程中的定位能力,,這些函數(shù)包括
關閉 利用C庫函數(shù)關閉文件依然是很簡單的操作:
例程:將第2節(jié)中的例程用C庫函數(shù)來實現(xiàn),。
4.小結 Linux提供的虛擬文件系統(tǒng)為多種文件系統(tǒng)提供了統(tǒng)一的接口,,Linux的文件編程有兩種途徑:基于Linux系統(tǒng)調(diào)用;基于C庫函數(shù),。這兩種編程所涉及到文件操作有新建,、打開、讀寫和關閉,,對隨機文件還可以定位,。本章對這兩種編程方法都給出了具體的實例。 |
|