UNIXLinux環(huán)境高級(jí)編程_第1頁(yè)
UNIXLinux環(huán)境高級(jí)編程_第2頁(yè)
UNIXLinux環(huán)境高級(jí)編程_第3頁(yè)
UNIXLinux環(huán)境高級(jí)編程_第4頁(yè)
UNIXLinux環(huán)境高級(jí)編程_第5頁(yè)
已閱讀5頁(yè),還剩38頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

低級(jí)文件I/O系統(tǒng)調(diào)用open() read() write()lseek() dup() dup2()fcntl() lockf() flock()ioctl() close()文件描述當(dāng)打開(kāi)一個(gè)現(xiàn)存文件或創(chuàng)建一個(gè)新文件時(shí),內(nèi)核向進(jìn)程返回一個(gè)文件描述符。當(dāng)讀、寫(xiě)一個(gè)文件時(shí),用open或creat返回的文件描述符標(biāo)識(shí)該文件,將其作為參數(shù)傳送給read、write、lseek和close等。按照慣例,UNIXshell使文件描述符:0-stdin 1-stdout 2-stderr在POSIX.1應(yīng)用程序中,標(biāo)準(zhǔn)I/O描述符被定義為:0-STDIN_FILENO; 1-STDOUT_FILENO; 2-STDERR_FILENO這些常數(shù)都定義在頭文件<unistd.h>中。文件描述符的范圍是0~OPEN_MAX。早期的UNIX版本采用的上限值是19(即20),現(xiàn)在很多系統(tǒng)則將其增加至256且可以以內(nèi)核參數(shù)的辦法設(shè)置,比方說(shuō)1024。原始系統(tǒng)數(shù)據(jù)類型在UNIX/Linux的開(kāi)發(fā)過(guò)程中用到的以_t結(jié)尾的數(shù)據(jù)為系統(tǒng)原始數(shù)據(jù)。系統(tǒng)原始數(shù)據(jù)在頭文件<sys/types.h>中被定義。出錯(cuò)處理UNIX函數(shù)出錯(cuò)時(shí),往常返回一個(gè)負(fù)值,而且整型變量errno通常設(shè)置為具有特定信息的一個(gè)值。例如,open函數(shù)如成功執(zhí)行則返回一個(gè)非負(fù)文件描述符,如出錯(cuò)則返回-1。在open出錯(cuò)時(shí),有大約15種不同的errno值。某些函數(shù)并不返回負(fù)值而是使用另一種約定。例如,返回一個(gè)指向?qū)ο蟮闹羔樀拇蠖鄶?shù)函數(shù),在出錯(cuò)時(shí),將返回一個(gè)null指針(NULL)。文件<errno.h>中定義了變量errno以及可以賦與它的各種常數(shù)。這些常數(shù)都以E開(kāi)頭。在Linux系統(tǒng)中,errno定義在頭文件/usr/include/asm/errno.h,多達(dá)124條。errnoPOSIX定義errno為:externinterrno;對(duì)于errno應(yīng)當(dāng)知道兩條規(guī)則:1:如果沒(méi)有出錯(cuò),則其值不會(huì)被一個(gè)例程清除。因此,僅當(dāng)函數(shù)的返回值指明出錯(cuò)時(shí),才檢驗(yàn)其值。2:任一函數(shù)都不會(huì)將errno值設(shè)置為0,在<errno.h>中定義的所有常數(shù)都不為0。錯(cuò)誤處理的標(biāo)準(zhǔn)函數(shù)strerror():功能:以字符串方式打印錯(cuò)誤信息。用法:#include<string.h>char*strerror(interrnum);返回:指向消息字符串的指針。perror()功能:在標(biāo)準(zhǔn)錯(cuò)誤上產(chǎn)生一條基于其參數(shù)串和errno的當(dāng)前值出錯(cuò)消息。用法:#include<stdio.h>voidperror(constchar*msg);輸出:首先輸出由msg指向的字符串,然后是一個(gè)冒號(hào),一個(gè)空格,然后是對(duì)應(yīng)于errno值的出錯(cuò)信息,然后是一個(gè)新行符。處理錯(cuò)誤的示例1#include <stdio.h>#include <errno.h>main(intargc,char*argv[]){ fprintf(stderr,"EACCES=%d:%s\n",EACCES,strerror(EACCES)); errno=ENOENT; perror(argv[0]);}結(jié)果:假設(shè),編譯后生成a.out,則輸出為:EACCES=13:Permissiondenied./a.out:Nosuchfileordirectory處理錯(cuò)誤的示例2#include <error.h>#include <fcntl.h>main(intargc,char*argv[]){ int i,fd; for(i=1;i<argc;i++){ if((fd=open(argv[i],O_RDWR))==-1) perror(argv[i]); elseclose(fd); }}open功能:打開(kāi)或創(chuàng)建一個(gè)文件,并返回一個(gè)文件描述符。用方:#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>intopen(constchar*name,intoflag);intopen(constchar*ame,intoflag,

mode_tmode);返回值:成功時(shí)為文件描述符,出錯(cuò)則為-1。出錯(cuò)時(shí)errno被設(shè)置。open的參數(shù)pathname是要打開(kāi)或創(chuàng)建的文件的名字。oflag參數(shù)可用來(lái)說(shuō)明此函數(shù)的多個(gè)選擇項(xiàng)。用下列一個(gè)或多個(gè)常數(shù)進(jìn)行或運(yùn)算構(gòu)成oflag參數(shù)(在fcntl.h中):?O_RDONLY:只讀打開(kāi)。 ?O_WRONLY:只寫(xiě)打開(kāi)。?O_RDWR:讀寫(xiě)打開(kāi) ?O_APPEND:追加方式。?O_CREAT:若不存在則創(chuàng)建它。需同時(shí)使用第三個(gè)參數(shù)mode。?O_EXCL:如果同時(shí)指定了O_CREAT,而文件已經(jīng)存在,則出錯(cuò)。這可測(cè)試一個(gè)文件是否存在,如果不存在則創(chuàng)建此文件成為一個(gè)原子操作。?O_TRUNC:果此文件存在,則將其長(zhǎng)度截短為0。?O_NOCTTY:如果pathname指的是終端設(shè)備,則不將此設(shè)備分配作為此進(jìn)程的控制終端。?O_NONBLOCK:如果pathname指的是特殊文件,此選擇項(xiàng)為此文件的本次打開(kāi)操作和后續(xù)的I/O操作設(shè)置非阻塞方式。creat功能:創(chuàng)建一個(gè)新文件用法:#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>intcreat(constchar*name,mode_tmode);返回:成功為只寫(xiě)打開(kāi)的文件描述符;出錯(cuò)為-1。出錯(cuò)時(shí)errno被設(shè)置。注意:此函數(shù)等效于:open(name,O_WRONLY|O_CREAT|O_TRUNC,mode);creat和open中可使用權(quán)限S_IRWXU用戶主的讀寫(xiě)和執(zhí)行權(quán)S_IRUSR用戶讀S_IWUSRS_IXUSR用戶寫(xiě)用戶執(zhí)行S_IRWXG組的讀寫(xiě)執(zhí)行S_IRGRP組讀S_IWGRP組寫(xiě)S_IXGRP組執(zhí)行S_IRWXO其它人的讀寫(xiě)執(zhí)行S_IROTH其它人讀S_IWOTH其它人寫(xiě)S_IXOTH其它執(zhí)行read功能:從描述符為fd的文件讀信息。用法:#include<unistd.h>ssize_tread(intfd,void*buff,size_tnbytes);返回:讀到的字節(jié)數(shù),若已到文件尾為0,若出錯(cuò)為-1。出錯(cuò)時(shí)errno被設(shè)置。在UNIX/Linux可重定義為:intread(intfd,char*buff,unsignednbytes);write功能:向已打開(kāi)的文件寫(xiě)數(shù)據(jù)。用法:#include<unistd.h>ssize_twrite(intfd,constvoid*buff,size_tnbytes);返回值:若成功為已寫(xiě)入的字節(jié)數(shù);出錯(cuò)為-1。出錯(cuò)時(shí)errno被設(shè)置。在UNIX/Linux可重定義為:intwrite(intfd,char*buff,unsignednbytes);文件位置指針文件位置指針:每個(gè)打開(kāi)文件都有一個(gè)與其相關(guān)聯(lián)的“當(dāng)前偏移量”。是從文件開(kāi)始處計(jì)算的字節(jié)數(shù)。通常,讀、寫(xiě)操作都從當(dāng)前文件位置處開(kāi)始,并使位移量增加所讀或?qū)懙淖止?jié)數(shù)。按系統(tǒng)默認(rèn),當(dāng)打開(kāi)一個(gè)文件時(shí),除非指定O_APPEND選擇項(xiàng),否則該偏移量被設(shè)置為0,即指向文件的開(kāi)始處。文件位置指針可以通過(guò)系統(tǒng)調(diào)用lseek來(lái)移動(dòng)。lseek功能:顯式地定位一個(gè)打開(kāi)文件的位置指針。用法:#include<sys/types.h>#include<unistd.h>off_tlseek(intfd,off_toffset,intwhence);返回值:若成功為新的文件位移,若出錯(cuò)為-1。出錯(cuò)時(shí)errno被設(shè)置。說(shuō)明:對(duì)參數(shù)offset的解釋與參數(shù)whence的值有關(guān):whence=SEEK_SET(=0),從文件開(kāi)始。whence=SEEK_CUR(=1),從當(dāng)前位置,offset可正可負(fù)。whence=SEEK_END(=2),從文件末尾,offset可為正或負(fù)。例:求文件的當(dāng)前位置指針:off_tcurrpos;currpos=lseek(fd,0,SEEK_CUR);這種方法也可用來(lái)確定所涉及的文件是否可以設(shè)置位移量。如果文件描述符引用的是一個(gè)管道或FIFO,則lseek返回-1,并將errno設(shè)置為EPIPE。文件的共享(三種數(shù)據(jù)結(jié)構(gòu))(1)v節(jié)點(diǎn)解構(gòu),即虛擬文件系統(tǒng)i節(jié)點(diǎn)結(jié)構(gòu)。指向磁盤(pán)i節(jié)點(diǎn)的指針和相關(guān)信息。(2)系統(tǒng)文件表,是內(nèi)核為所有打開(kāi)文件維持一張文件表。文件狀態(tài)標(biāo)志(讀、寫(xiě)、同步、非阻塞等)。當(dāng)前文件指針。指向v節(jié)點(diǎn)解構(gòu)的指針。(3)進(jìn)程文件表,每個(gè)進(jìn)程在執(zhí)行過(guò)程中都有一個(gè)記錄它自己打開(kāi)的文件描述符表。文件描述符標(biāo)志。指向系統(tǒng)打開(kāi)文件表一個(gè)表項(xiàng)的指針。三種數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系進(jìn)程間文件共享情況dup與dup2功能:復(fù)制已有的文件描述符用法:#include<unistd.h>intdup(intori_fd);intdup2(intori_fd,intnew_fd);返回值:若成功返回新的描述符,失敗時(shí)返回-1;出錯(cuò)時(shí)errno被設(shè)置。說(shuō)明:新描述符與原來(lái)的描述具有相同的文件表,共享同一個(gè)文件標(biāo)志;使用dup2時(shí),若new_fd為已打開(kāi)者,則先關(guān)閉之。進(jìn)程內(nèi)文件共享情況文件的互斥伴隨文件的共享而來(lái)的是文件的互斥訪問(wèn)。這表現(xiàn)為同一文件或其中的一部分不允許兩進(jìn)程同時(shí)訪問(wèn),若一個(gè)文件的某一部分存在被某一進(jìn)程以寫(xiě)方式訪問(wèn),另一進(jìn)程也要訪問(wèn)同一個(gè)地方則它必須等待。實(shí)現(xiàn)文件互斥訪問(wèn)的辦法是以互斥方式打開(kāi)文件或文件上鎖。文件的互斥打開(kāi),可以在打開(kāi)文件是使用O_EXCL參數(shù)。文件上鎖可以使用flock()系統(tǒng)調(diào)用。flock()功能:為一個(gè)打開(kāi)的文件描述符上鎖或解鎖用法:#include <sys/file.h>intflock(intfd,intop);參數(shù):fd為已經(jīng)打開(kāi)的文件描述符op為對(duì)fd的操作方式:LOCK_SH:為文件fd上一個(gè)共享鎖,在給定時(shí)間內(nèi)可由多個(gè)進(jìn)程共享此文件鎖;LOCK_EX:為文件fd加一個(gè)排它鎖,在給定時(shí)刻只能有一個(gè)進(jìn)程使用使用此文件鎖;LOCK_UN:去除文件fd上文件鎖。返回值:成功時(shí)返回0,否則返回-1,同時(shí)errno被設(shè)置。說(shuō)明:由flock()創(chuàng)建的文件鎖,與打開(kāi)的文件fd相關(guān)聯(lián),且同一個(gè)文件不能同時(shí)具有共享鎖和排它鎖。這意味著如果一個(gè)描述符是由dup()或dup2()復(fù)制的,則它們擁有相同的文件鎖。如果一個(gè)文件已經(jīng)被一個(gè)進(jìn)程上一個(gè)非“兼容”鎖,當(dāng)另一個(gè)進(jìn)程也要為此文件加鎖時(shí)可能被阻塞。lockf功能用于對(duì)一個(gè)打開(kāi)的文件的部分進(jìn)行加鎖,實(shí)現(xiàn)進(jìn)程間對(duì)此部分的互斥訪問(wèn)。用法#include<sys/file.h>intlockf(intfd,intcmd,off_tlen);返回值若成功返回0,否則返回-1,并設(shè)置errno。參數(shù)fd是以寫(xiě)方式打開(kāi)的文件描述符;cmd是鎖定方式:F_ULOCK(=0):解鎖。F_LOCK(=1):加鎖。若要鎖的部分的局部已經(jīng)被其它進(jìn)程鎖定,則lock()被阻塞。在同一進(jìn)程中,若上鎖部分重疊,則上鎖后,原先鎖定部分和本次鎖定部分合并。鎖定部分當(dāng)調(diào)用lockf()釋放或進(jìn)程關(guān)閉文件時(shí)解鎖。這種鎖不會(huì)被子進(jìn)程繼承。F_TLOCK(=2):作用與F_LOCK同但不會(huì)被阻塞,若未上鎖則加鎖,若已經(jīng)上鎖則返回-1.F_TEST(=3):測(cè)試是否上鎖,若未上鎖返回0,若已經(jīng)上鎖則返回-1。len是要鎖定的文件長(zhǎng)度。設(shè)文件位置指針為pos,則當(dāng)len>0時(shí),鎖定長(zhǎng)度為pos~pos-1;若len<0,則鎖定長(zhǎng)度為pos-len~pos-1;若len=0,則鎖定長(zhǎng)度為從pos開(kāi)始到文件結(jié)束的所有部分。fcntl功能:控制和改變已經(jīng)打開(kāi)文件的屬性。用法:#include<sys/types.h>#include<unistd.h>#include<fcntl.h>intfcntl(intfd,intcmd,longarg);intfcntl(intfd,intcmd,structflock*lock);返回值:若成功則依賴于cmd,若出錯(cuò)為-1;出錯(cuò)時(shí)errno被設(shè)置。fcntl函數(shù)有五種功能復(fù)制一個(gè)現(xiàn)存的描述符(cmd=F_DUPFD)新文件描述符作為值返回。新描述符與fd共享同一文件表項(xiàng);(參見(jiàn)dup()和dup2())

獲得/設(shè)置文件描述符標(biāo)記(cmd=F_GETFD/F_SETFD);對(duì)應(yīng)于fd的文件描述符標(biāo)志作為函數(shù)值返回。獲得/設(shè)置文件狀態(tài)標(biāo)志(cmd=F_GETFL/F_SETFL);新標(biāo)志值按第三個(gè)參數(shù)設(shè)置。可以更改的幾個(gè)標(biāo)志是:O_APPEND,O_NONBLOCK,O_SYNC和O_ASYNC。獲得/設(shè)置異步I/O有權(quán)(cmd=F_GETOWN/F_SETOWN);獲取或接收當(dāng)前接收SIGIO和SIGURG信號(hào)的進(jìn)程ID或進(jìn)程組ID。獲得/設(shè)置記錄鎖(cmd=F_GETLK,F_SETLK或F_SETLKW)。ioctl函數(shù)ioctl函數(shù)是I/O操作的雜物箱。不能用本章中其他函數(shù)表示的I/O操作通常都能用ioctl表示。終端I/O是ioctl的最大使用方面(POSIX.1已經(jīng)用新的函數(shù)代替ioctl進(jìn)行終端I/O操作)。ioctl更多的是用于設(shè)備控制,比如磁盤(pán)的格式化,MODEM設(shè)備,磁帶的快進(jìn)、快倒等。原子操作在多進(jìn)程(線程)的操作系統(tǒng)中不能被其它進(jìn)程(線程)打斷的操作就叫原子操作,文件的原子操作是指操作文件時(shí)的不能被其它進(jìn)程(線程)打斷的操作。一般來(lái)說(shuō),一次系統(tǒng)調(diào)用所做的工作是一個(gè)原子操作,也就是在這個(gè)操作過(guò)程中不會(huì)被其它“過(guò)程”打斷。這是因?yàn)?,在Unix系統(tǒng)中,系統(tǒng)調(diào)用在內(nèi)核中執(zhí)行,且在此次系統(tǒng)調(diào)用返回前,其它進(jìn)程是不能再內(nèi)核的。一個(gè)原子操作可以由多個(gè)步驟組成,但它的執(zhí)行過(guò)程中,要么一次執(zhí)行完畢,要么一步也不執(zhí)行。原子操作示例向文件的末尾追加一些數(shù)據(jù),可以通過(guò)先將文件打開(kāi),再將文件指針移到文件尾部,最后再寫(xiě)入信息的辦法。也可采用先用追加方式打開(kāi),然后再寫(xiě)入信息的辦法。方法1main(){ intfd; char*file=”myfile”,*strtowri=”appendtest\n”; if((fd=open(file,O_RDWR))==-1){ perror(“Fileopen”);exit(-1); } if(lseek(fd,0L,2)<0){ perror(“l(fā)seekerror”);close(fd);exit(-2); } if((write(fd,strtowr,strlen(strtowr)!=sizeof(strtowrite)){ perror(“writeerror”);close(fd);exit(-3) } close(fd);}方法2main(){ intfd; char*file=”myfile”,*strtowrite=”appendtest\n”; if((fd=open(file,O_APPEND))==-1) perror(”Fileopen”);exit(-1); } if((write(fd,strtowr,strlen(strtowr)!=sizeof(strtowr)){ perror(”writeerror”);close(fd);exit(-3) } close(fd);}示例1:向文件追加內(nèi)容向一個(gè)文件追加信息,若文件已經(jīng)存在則追加信息,若不存在則,先創(chuàng)建之,然后再寫(xiě)入信息。先將文件以O(shè)_RDWR|O_CREAT|O_APPEND方式打開(kāi),意思是當(dāng)文件是存在時(shí)則以某權(quán)限(比如0644)創(chuàng)建它,若文件已經(jīng)存在則將文件指針定位到文件尾部。代碼#include <errno.h>#include <sys/stat.h>#include <sys/fcntl.h>main(){ int fd,j; char *myc="Thisismy1stprogram!!\n"; char *myf="myfile"; if((fd=open(myf,O_RDWR|O_CREAT|O_APPEND,0644))==-1){ perror(myf); exit(errno);} if(write(fd,myc,strlen(myc))!=strlen(myc)) { perror(myc); close(fd);exit(errno);} close(fd);}示例:文件長(zhǎng)度的確定#include<fcntl.h>#include<sys/types.h>#include<unistd.h>#include<string.h>main(){ intfd; off_tlen; char*filename="myfile"; if((fd=open(filename,O_RDWR))==-1) { perror(filename);exit(-1); } if((len=lseek(fd,0,SEEK_END))==-1){ perror("lseek");close(fd);exit(-2); } printf("Thelenghtoffile%s'sis%ld\n",filename,len); close(fd);exit(0);}示例3:記錄格式文件操作設(shè)文件myrec是記錄格式的,其數(shù)據(jù)格式為:姓名:8個(gè)字符年齡:3個(gè)數(shù)字字符性別:1個(gè)字符(M/m表示男,F(xiàn)/f表示女)其中的第3個(gè)記錄的內(nèi)容

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論