?? 5.txt
字號(hào):
5.文件處理
當(dāng)我們要處理文件時(shí),我們必需先調(diào)用apr_file_open()函數(shù),這兒是它的原型聲明:
/* 摘自apr_file_io.h */
APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **newf, const char *fname,
apr_int32_t flag, apr_fileperms_t perm,
apr_pool_t *pool);
第一個(gè)參數(shù)是結(jié)果參數(shù),其類(lèi)型為apr_file_t**,即通過(guò)調(diào)用apr_file_open()來(lái)創(chuàng)建一個(gè)apr_file_t對(duì)象。第二個(gè)參數(shù)是文件路徑,第三個(gè)參數(shù)是位標(biāo)志,在apr_file_io.h文件中定義。第四個(gè)參數(shù)是對(duì)新創(chuàng)建的文件設(shè)置的訪問(wèn)權(quán)限,其值是也是位標(biāo)志,在apr_file_io.h中定義。例如,如果你想創(chuàng)建一個(gè)訪問(wèn)權(quán)限為0600的文件,只有文件擁有者可以讀寫(xiě)它,那么你可以指定其值為APR_UREAD|APR_UWRITE。在通常情況下,文件訪問(wèn)權(quán)限的值你可以設(shè)置為APR_OS_DEFAULT。第五個(gè)參數(shù)是要使用的內(nèi)存池,毋庸置疑,你得使用apr_pool_create()函數(shù)去事先創(chuàng)建它。
打開(kāi)文件后,我們就可以使用其他的API函數(shù)來(lái)處理文件了,這些API函數(shù)可以在apr_file_io.h文件中找到?;镜挠衋pr_file_read()和apr_file_write()函數(shù),如你所想,apr_file_read()使我們可以從文件中讀取一些東西,而apr_file_write()允許我們向文件寫(xiě)入一些東西,其函數(shù)原型聲明如下:
/* 摘自apr_file_io.h */
APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf,
apr_size_t *nbytes);
APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf,
apr_size_t *nbytes);
這兩個(gè)函數(shù)的第三個(gè)參數(shù)均為輸入輸出參數(shù),意思是說(shuō),在調(diào)用函數(shù)時(shí)我們指定它的值為輸入值的長(zhǎng)度,而在函數(shù)返回時(shí)它的值為結(jié)果的長(zhǎng)度。具體而言,apr_file_read()返回的是讀取字節(jié)的長(zhǎng)度,apr_file_write()返回的是寫(xiě)入字節(jié)的長(zhǎng)度。這兒有一個(gè)例子:
/* 關(guān)于apr_file_write()的偽代碼 */
strcpy(outbuf, "123456789");
apr_size_t outlen = strlen(outbuf);
rv = apr_file_write(fp, outbuf, &outlen);
printf("apr_file_write() rv = %d, nbytes = %d\n", rv, outlen);
這個(gè)例子中,在調(diào)用apr_file_write()之前,變量'outlen'的值是9,通過(guò)使用&outlen這樣的形式作為第三個(gè)參數(shù),告訴
apr_file_write()函數(shù)可寫(xiě)的長(zhǎng)度是9,當(dāng)apr_file_write()函數(shù)返回時(shí),'outlen'的值變?yōu)閷?shí)際寫(xiě)入的長(zhǎng)度。如果是本地文件,它的值常常是9,理論上,它的值可以變小(例如當(dāng)磁盤(pán)滿(mǎn)的時(shí)候)。
我們只能調(diào)用apr_file_close()函數(shù)去關(guān)閉文件,除此之外,也可以通過(guò)銷(xiāo)毀apr_file_open()函數(shù)相關(guān)的內(nèi)存池來(lái)實(shí)現(xiàn)文件的關(guān)閉。我比較喜歡顯式地調(diào)用apr_file_close()函數(shù)去關(guān)閉文件,不過(guò)這僅僅是我的意見(jiàn)。
注:在不同的libapr版本之間存在著一些源程序的兼容性問(wèn)題,apr_file_open()的第三個(gè)參數(shù)自libapr 1.1.0版本這后加上了APR_FOPEN_前綴,但是之前的版本卻沒(méi)有這個(gè)前綴。可以使用APR_FOPEN_CREATE代替APR_CREATE,請(qǐng)查閱你使用的libapr版本的apr_file_io.h文件。同樣地,apr_file_open()的第四個(gè)參數(shù)自libapr 1.1.0版本之后,添加了APR_FPROT_前綴。
注:這兒還有一個(gè)兼容性的問(wèn)題是關(guān)于文件路徑分割符的,Unix(POSIX)系統(tǒng)使用斜線('/'),MS-Windows使用反斜線('\')作為分割符。如果你要寫(xiě)一個(gè)能在Unix和MS-Windows系統(tǒng)上都能運(yùn)行的應(yīng)用程序,我推薦你統(tǒng)一地在文件路徑中使用斜線('/')作為分割符,因?yàn)镸S-Windows中可以接受識(shí)別它。
注:特別注意apr_file_gets()的用法,沒(méi)有APR_BUFFERED的apr_file_gets()調(diào)用而將很大的影響效率,這是因?yàn)閍pr_file_gets()內(nèi)部將對(duì)每一個(gè)字節(jié)都會(huì)調(diào)用apr_file_read()。記住要使用apr_file_gets()時(shí),打開(kāi)文件必須加上APR_BUFFERED標(biāo)志。
在以下的情況我不推薦你使用APR_BUFFERED標(biāo)志:
1.當(dāng)你使用mmap映射一個(gè)文件時(shí)(因?yàn)楫?dāng)mmap一個(gè)APR_BUFFERED文件時(shí)會(huì)產(chǎn)生錯(cuò)誤)
2.沒(méi)有讀/寫(xiě)(例如僅僅是為了鎖住一個(gè)文件)
3.你能確定你使用一個(gè)大內(nèi)存緩沖區(qū)來(lái)讀/寫(xiě)文件。
注:當(dāng)使用APR_BUFFERED標(biāo)志打開(kāi)了一個(gè)文件并且對(duì)一個(gè)文件調(diào)用apr_file_trunc()函數(shù)時(shí),你必須在調(diào)用apr_file_trunc()之前調(diào)用apr_file_flush()之前,否則,文件將被損壞。
注: 當(dāng)使用APR_BUFFERED標(biāo)志打開(kāi)了一個(gè)文件并且這個(gè)文件被多個(gè)線程共享,那么APR_XTHREAD標(biāo)志也是必需的。不幸的是,APR_XTHREAD標(biāo)志在Windows系統(tǒng)有另一面的影響,我的經(jīng)驗(yàn)告訴我不要在Windows系統(tǒng)中使用APR_XTHREAD標(biāo)志。
可以得到文件的各種信息,例如大小,時(shí)間,擁有者,訪問(wèn)權(quán)限等等,這些信息存放在apr_finfo_t結(jié)構(gòu)體中,apr_finfo_t在文件apr_file_info.h中有定義。這里有兩個(gè)相關(guān)的API函數(shù):
/* 摘自 apr_file_io.h */
APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo, apr_int32_t wanted, apr_file_t *thefile);
/* 摘自 apr_file_info.h */
APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *pool);
apr_file_info_get()函數(shù)要求apr_file_t對(duì)象,apr_stat()函數(shù)要求文件路徑。如果已經(jīng)打開(kāi)了文件并且生成了apr_file_t對(duì)象,那么最好使用apr_file_info_get();否則,可以調(diào)用apr_stat()。與其他類(lèi)型不同,apr_finfo_t是一個(gè)完整類(lèi)型,這兩個(gè)api函數(shù)并沒(méi)有生成該對(duì)象,我們只能顯式地創(chuàng)建它并為其分配內(nèi)存。典型地,它在當(dāng)前棧中創(chuàng)建,這是因?yàn)槲覀兿胫酪恍┲T如文件大小和時(shí)間的屬性。注意如apr_finfo_t::fname等一些內(nèi)存,如果是創(chuàng)建在內(nèi)存池中的,這將產(chǎn)生一些錯(cuò)誤。請(qǐng)查看finfo-sample.c文件,了解它的用法。
有一些文件處理函數(shù)是在文件名基礎(chǔ)上運(yùn)行的,例如apr_file_remove()和apr_file_copy(),它們?cè)赼pr_file_io.h和arp_file_info.h文件中能找到。
注:一些API函數(shù)帶有"wanted"參數(shù), 通過(guò)指定該參數(shù)的位標(biāo)志得到文件的屬性。 這些函數(shù)是apr_dir_read(), apr_stat(), apr_lstat()和apr_file_info_get()。注意"wanted"參數(shù)的值將會(huì)超出操作系統(tǒng)的文件系統(tǒng)的支持,在這種情況下,該API函數(shù)將返回APR_INCOMPLETE。
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -