日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux文件操作函数

發(fā)布時間:2023/12/20 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux文件操作函数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言: 我們在這一節(jié)將要討論linux下文件操作的各個函數(shù). 文件的創(chuàng)建和讀寫 文件的各個屬性 目錄文件的操作 管道文件 -------------------------------------------------------------------------------- 1。文件的創(chuàng)建和讀寫 我假設(shè)你已經(jīng)知道了標準級的文件操作的各個函數(shù)(fopen,fread,fwrite等等).當然如果你不清楚的話也不要著急.我們討論的系統(tǒng)級的文件操作實際上是為標準級文件操作服務(wù)的. 當我們需要打開一個文件進行讀寫操作的時候,我們可以使用系統(tǒng)調(diào)用函數(shù)open.使用完成以后我們調(diào)用另外一個close函數(shù)進行關(guān)閉操作. #include #include #include #include int open(const char *pathname,int flags); int open(const char *pathname,int flags,mode_t mode); int close(int fd); open函數(shù)有兩個形式.其中pathname是我們要打開的文件名(包含路徑名稱,缺省是認為在當前路徑下面).flags可以去下面的一個值或者是幾個值的組合. O_RDONLY:以只讀的方式打開文件. O_WRONLY:以只寫的方式打開文件. O_RDWR:以讀寫的方式打開文件. O_APPEND:以追加的方式打開文件. O_CREAT:創(chuàng)建一個文件. O_EXEC:如果使用了O_CREAT而且文件已經(jīng)存在,就會發(fā)生一個錯誤. O_NOBLOCK:以非阻塞的方式打開一個文件. O_TRUNC:如果文件已經(jīng)存在,則刪除文件的內(nèi)容. 前面三個標志只能使用任意的一個.如果使用了O_CREATE標志,那么我們要使用open的第二種形式.還要指定mode標志,用來表示文件的訪問權(quán)限.mode可以是以下情況的組合. ----------------------------------------------------------------- S_IRUSR????????用戶可以讀?????S_IWUSR????????用戶可以寫 S_IXUSR????????用戶可以執(zhí)行???S_IRWXU????????用戶可以讀寫執(zhí)行 ----------------------------------------------------------------- S_IRGRP????????組可以讀???????S_IWGRP????????組可以寫 S_IXGRP????????組可以執(zhí)行?????S_IRWXG????????組可以讀寫執(zhí)行 ----------------------------------------------------------------- S_IROTH?????????其他人可以讀????S_IWOTH?????????其他人可以寫 S_IXOTH?????????其他人可以執(zhí)行??S_IRWXO?????????其他人可以讀寫執(zhí)行 ----------------------------------------------------------------- S_ISUID????????設(shè)置用戶執(zhí)行ID??S_ISGID???????????????設(shè)置組的執(zhí)行ID ----------------------------------------------------------------- 我們也可以用數(shù)字來代表各個位的標志.Linux總共用5個數(shù)字來表示文件的各種權(quán)限. 00000.第一位表示設(shè)置用戶ID.第二位表示設(shè)置組ID,第三位表示用戶自己的權(quán)限位,第四位表示組的權(quán)限,最后一位表示其他人的權(quán)限. 每個數(shù)字可以取1(執(zhí)行權(quán)限),2(寫權(quán)限),4(讀權(quán)限),0(什么也沒有)或者是這幾個值的和. 比如我們要創(chuàng)建一個用戶讀寫執(zhí)行,組沒有權(quán)限,其他人讀執(zhí)行的文件.設(shè)置用戶ID位那么我們可以使用的模式是--1(設(shè)置用戶ID)0(組沒有設(shè)置)7(1+2+4)0(沒有權(quán)限,使用缺省)5(1+4)即10705: open("temp",O_CREAT,10705); 如果我們打開文件成功,open會返回一個文件描述符.我們以后對文件的所有操作就可以對這個文件描述符進行操作了. 當我們操作完成以后,我們要關(guān)閉文件了,只要調(diào)用close就可以了,其中fd是我們要關(guān)閉的文件描述符. 文件打開了以后,我們就要對文件進行讀寫了.我們可以調(diào)用函數(shù)read和write進行文件的讀寫. #include ssize_t??read(int fd, void *buffer,size_t count); ssize_t write(int fd, const void *buffer,size_t count); fd是我們要進行讀寫操作的文件描述符,buffer是我們要寫入文件內(nèi)容或讀出文件內(nèi)容的內(nèi)存地址.count是我們要讀寫的字節(jié)數(shù). 對于普通的文件read從指定的文件(fd)中讀取count字節(jié)到buffer緩沖區(qū)中(記住我們必須提供一個足夠大的緩沖區(qū)),同時返回count. 如果read讀到了文件的結(jié)尾或者被一個信號所中斷,返回值會小于count.如果是由信號中斷引起返回,而且沒有返回數(shù)據(jù),read會返回-1,且設(shè)置errno為EINTR.當程序讀到了文件結(jié)尾的時候,read會返回0. write從buffer中寫count字節(jié)到文件fd中,成功時返回實際所寫的字節(jié)數(shù). 下面我們學(xué)習(xí)一個實例,這個實例用來拷貝文件. #include #include #include #include #include #include #include #define????????BUFFER_SIZE????1024 int main(int argc,char **argv) { int from_fd,to_fd; int bytes_read,bytes_write; char buffer[BUFFER_SIZE]; char *ptr; if(argc!=3) { fprintf(stderr,"Usage:%s fromfile tofile\n\a",argv[0]); exit(1); } /*??????打開源文件?????*/ if((from_fd=open(argv[1],O_RDONLY))==-1) { fprintf(stderr,"Open %s Error:%s\n",argv[1],strerror(errno)); exit(1); } /*??????創(chuàng)建目的文件???*/ if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1) { fprintf(stderr,"Open %s Error:%s\n",argv[2],strerror(errno)); exit(1); } /*??????以下代碼是一個經(jīng)典的拷貝文件的代碼????*/ while(bytes_read=read(from_fd,buffer,BUFFER_SIZE)) { /*??????一個致命的錯誤發(fā)生了???*/ if((bytes_read==-1)&&(errno!=EINTR)) break; else if(bytes_read>0) { ptr=buffer; while(bytes_write=write(to_fd,ptr,bytes_read)) { /*??????一個致命錯誤發(fā)生了?????*/ if((bytes_write==-1)&&(errno!=EINTR))break; /*??????寫完了所有讀的字節(jié)?????*/ else if(bytes_write==bytes_read) break; /*??????只寫了一部分,繼續(xù)寫????*/ else if(bytes_write>0) { ptr+=bytes_write; bytes_read-=bytes_write; } } /*??????寫的時候發(fā)生的致命錯誤?*/ if(bytes_write==-1)break; } } close(from_fd); close(to_fd); exit(0); } 2。文件的各個屬性 文件具有各種各樣的屬性,除了我們上面所知道的文件權(quán)限以外,文件還有創(chuàng)建時間,大小等等屬性. 有時侯我們要判斷文件是否可以進行某種操作(讀,寫等等).這個時候我們可以使用access函數(shù). #include int access(const char *pathname,int mode); pathname:是文件名稱,mode是我們要判斷的屬性.可以取以下值或者是他們的組合. R_OK文件可以讀,W_OK文件可以寫,X_OK文件可以執(zhí)行,F_OK文件存在.當我們測試成功時,函數(shù)返回0,否則如果有一個條件不符時,返回-1. 如果我們要獲得文件的其他屬性,我們可以使用函數(shù)stat或者fstat. #include #include int stat(const char *file_name,struct stat *buf); int fstat(int filedes,struct stat *buf); struct stat { dev_t??????????st_dev;????????/*?設(shè)備???*/ ino_t??????????st_ino;????????/*?節(jié)點???*/?? mode_t?????????st_mode;???????/*?模式???*/ nlink_t????????st_nlink;??????/*?硬連接?*/ uid_t??????????st_uid;????????/*?用戶ID */ gid_t??????????st_gid;????????/*?組ID???*/ dev_t??????????st_rdev;???????/*?設(shè)備類型?*/ off_t??????????st_off;????????/*?文件字節(jié)數(shù)?*/ unsigned long?st_blksize;????/*?塊大小?*/ unsigned long??st_blocks;?????/*?塊數(shù)???*/ time_t?????????st_atime;??????/*?最后一次訪問時間?*/ time_t?????????st_mtime;??????/*?最后一次修改時間?*/ time_t?????????st_ctime;??????/*?最后一次改變時間(指屬性) */ }; stat用來判斷沒有打開的文件,而fstat用來判斷打開的文件.我們使用最多的屬性是st_mode.通過著屬性我們可以判斷給定的文件是一個普通文件還是一個目錄,連接等等.可以使用下面幾個宏來判斷. S_ISLNK(st_mode):是否是一個連接.S_ISREG是否是一個常規(guī)文件.S_ISDIR是否是一個目錄S_ISCHR是否是一個字符設(shè)備.S_ISBLK是否是一個塊設(shè)備S_ISFIFO是否 是一個FIFO文件.S_ISSOCK是否是一個SOCKET文件.?我們會在下面說明如何使用這幾個宏的. 3。目錄文件的操作 在我們編寫程序的時候,有時候會要得到我們當前的工作路徑。C庫函數(shù)提供了getcwd來解決這個問題。 #include char *getcwd(char *buffer,size_t size); 我們提供一個size大小的buffer,getcwd會把我們當前的路徑考到buffer中.如果buffer太小,函數(shù)會返回-1和一個錯誤號. Linux提供了大量的目錄操作函數(shù),我們學(xué)習(xí)幾個比較簡單和常用的函數(shù). #include #include #include #include #include int mkdir(const char *path,mode_t mode); DIR *opendir(const char *path); struct dirent *readdir(DIR *dir); void rewinddir(DIR *dir); off_t telldir(DIR *dir); void??seekdir(DIR *dir,off_t off); int closedir(DIR *dir); struct dirent { long????d_ino; off_t???d_off; unsigned short d_reclen; char????d_name[NAME_MAX+1];????/*?文件名稱????*/ mkdir很容易就是我們創(chuàng)建一個目錄,opendir打開一個目錄為以后讀做準備.readdir讀一個打開的目錄.rewinddir是用來重讀目錄的和我們學(xué)的rewind函數(shù)一樣.closedir是關(guān)閉一個目錄.telldir和seekdir類似與ftee和fseek函數(shù). 下面我們開發(fā)一個小程序,這個程序有一個參數(shù).如果這個參數(shù)是一個文件名,我們輸出這個文件的大小和最后修改的時間,如果是一個目錄我們輸出這個目錄下所有文件的大小和修改時間. #include #include #include #include #include #include #include static int get_file_size_time(const char *filename) { struct stat statbuf; if(stat(filename,&statbuf)==-1) { printf("Get stat on %s Error:%s\n", filename,strerror(errno)); return(-1); } if(S_ISDIR(statbuf.st_mode))return(1); if(S_ISREG(statbuf.st_mode)) printf("%s size:%ld bytes\tmodified at %s", filename,statbuf.st_size,ctime(&statbuf.st_mtime));?? return(0); } int main(int argc,char **argv) { DIR *dirp; struct dirent *direntp; int stats; if(argc!=2) { printf("Usage:%s filename\n\a",argv[0]); exit(1); } if(((stats=get_file_size_time(argv[1]))==0)||(stats==-1))exit(1); if((dirp=opendir(argv[1]))==NULL) { printf("Open Directory %s Error:%s\n", argv[1],strerror(errno)); exit(1); } while((direntp=readdir(dirp))!=NULL) if(get_file_size_time(direntp-< cat Linux提供了許多的過濾和重定向程序,比如more 4。管道文件?} exit(1); closedir(dirp);> | <<等等重定向操作符.在這些過濾和重 定向程序當中,都用到了管道這種特殊的文件.系統(tǒng)調(diào)用pipe可以創(chuàng)建一個管道. #include int pipe(int fildes[2]); pipe調(diào)用可以創(chuàng)建一個管道(通信緩沖區(qū)).當調(diào)用成功時,我們可以訪問文件描述符fildes[0],fildes[1].其中fildes[0]是用來讀的文件描述符,而fildes[1]是用來寫的文件描述符. 在實際使用中我們是通過創(chuàng)建一個子進程,然后一個進程寫,一個進程讀來使用的. 關(guān)于進程通信的詳細情況請查看進程通信 #include #include #include #include #include #include #include #define??BUFFER????????255 int main(int argc,char **argv) { char buffer[BUFFER+1]; int fd[2]; if(argc!=2) { fprintf(stderr,"Usage:%s string\n\a",argv[0]); exit(1); } if(pipe(fd)!=0) { fprintf(stderr,"Pipe Error:%s\n\a",strerror(errno)); exit(1); } if(fork()==0) { close(fd[0]); printf("Child[%d] Write to pipe\n\a",getpid()); snprintf(buffer,BUFFER,"%s",argv[1]); write(fd[1],buffer,strlen(buffer)); printf("Child[%d] Quit\n\a",getpid()); exit(0); } else { close(fd[1]); printf("Parent[%d] Read from pipe\n\a",getpid()); memset(buffer,'\0',BUFFER+1); read(fd[0],buffer,BUFFER); printf("Parent[%d] Read:%s\n",getpid(),buffer); exit(1); } } 為了實現(xiàn)重定向操作,我們需要調(diào)用另外一個函數(shù)dup2. #include int dup2(int oldfd,int newfd); dup2將用oldfd文件描述符來代替newfd文件描述符,同時關(guān)閉newfd文件描述符.也就是說, 所有向newfd操作都轉(zhuǎn)到oldfd上面.下面我們學(xué)習(xí)一個例子,這個例子將標準輸出重定向到一個文件. #include #include #include #include #include #include #include #define??BUFFER_SIZE???1024 int main(int argc,char **argv) { int fd; char buffer[BUFFER_SIZE]; if(argc!=2) { fprintf(stderr,"Usage:%s outfilename\n\a",argv[0]); exit(1); } if((fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1) { fprintf(stderr,"Open %s Error:%s\n\a",argv[1],strerror(errno)); exit(1); } if(dup2(fd,STDOUT_FILENO)==-1) { fprintf(stderr,"Redirect Standard Out Error:%s\n\a",strerror(errno)); exit(1); } fprintf(stderr,"Now,please input string"); fprintf(stderr,"(To quit use CTRL+D)\n");? while(1) { fgets(buffer,BUFFER_SIZE,stdin); if(feof(stdin))break; write(STDOUT_FILENO,buffer,strlen(buffer)); } exit(0); } 好了,文件一章我們就暫時先討論到這里,學(xué)習(xí)好了文件的操作我們其實已經(jīng)可以寫出一些比較有用的程序了.我們可以編寫一個實現(xiàn)例如dir,mkdir,cp,mv等等常用的文件操作命令了. 想不想自己寫幾個試一試呢? 前言:Linux下的時間概念 這一章我們學(xué)習(xí)Linux的時間表示和計算函數(shù) 時間的表示 時間的測量 計時器的使用 1。時間表示?????在程序當中,我們經(jīng)常要輸出系統(tǒng)當前的時間,比如我們使用date命令的輸出結(jié)果.這個時候我們可以使用下面兩個函數(shù) #include time_t??time(time_t *tloc); char????*ctime(const time_t *clock); time函數(shù)返回從1970年1月1日0點以來的秒數(shù).存儲在time_t結(jié)構(gòu)之中.不過這個函數(shù)的返回值對于我們來說沒有什么實際意義.這個時候我們使用第二個函數(shù)將秒數(shù)轉(zhuǎn)化為字符串.?這個函數(shù)的返回類型是固定的:一個可能值為. Thu Dec 7 14:58:59 2000?這個字符串的長度是固定的為26 2。時間的測量?????有時候我們要計算程序執(zhí)行的時間.比如我們要對算法進行時間分析.這個時候可以使用下面這個函數(shù). #include int gettimeofday(struct timeval *tv,struct timezone *tz); strut timeval { long????tv_sec;????????/*??????秒數(shù)???????????*/ long????tv_usec;???????/*??????微秒數(shù)?????????*/ }; gettimeofday將時間保存在結(jié)構(gòu)tv之中.tz一般我們使用NULL來代替. #include?

int getitimer(int which,struct itimerval *value);

int setitimer(int which,struct itimerval *newval, struct itimerval *oldval); struct itimerval { struct timeval it_interval; struct timeval it_value; } getitimer函數(shù)得到間隔計時器的時間值.保存在value中?setitimer函數(shù)設(shè)置間隔計時器的時間值為newval.并將舊值保存在oldval中. which表示使用三個計時器中的哪一個. itimerval結(jié)構(gòu)中的it_value是減少的時間,當這個值為0的時候就發(fā)出相應(yīng)的信號了.?然后設(shè)置為it_interval值. #include #include #include #include #include #define????????PROMPT??"時間已經(jīng)過去了兩秒鐘\n\a" char *prompt=PROMPT; unsigned int len; void prompt_info(int signo) { write(STDERR_FILENO,prompt,len); } void init_sigaction(void) { struct sigaction act; act.sa_handler=prompt_info; act.sa_flags=0; sigemptyset(&act.sa_mask); sigaction(SIGPROF,&act,NULL); } void init_time() { struct itimerval value; value.it_value.tv_sec=2; value.it_value.tv_usec=0; value.it_interval=value.it_value; setitimer(ITIMER_PROF,&value,NULL); } int main() { len=strlen(prompt); init_sigaction(); init_time(); while(1); exit(0); }

總結(jié)

以上是生活随笔為你收集整理的linux文件操作函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。