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

歡迎訪問 生活随笔!

生活随笔

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

linux

linux文件操作函数

發布時間:2023/12/20 linux 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux文件操作函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言: 我們在這一節將要討論linux下文件操作的各個函數. 文件的創建和讀寫 文件的各個屬性 目錄文件的操作 管道文件 -------------------------------------------------------------------------------- 1。文件的創建和讀寫 我假設你已經知道了標準級的文件操作的各個函數(fopen,fread,fwrite等等).當然如果你不清楚的話也不要著急.我們討論的系統級的文件操作實際上是為標準級文件操作服務的. 當我們需要打開一個文件進行讀寫操作的時候,我們可以使用系統調用函數open.使用完成以后我們調用另外一個close函數進行關閉操作. #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函數有兩個形式.其中pathname是我們要打開的文件名(包含路徑名稱,缺省是認為在當前路徑下面).flags可以去下面的一個值或者是幾個值的組合. O_RDONLY:以只讀的方式打開文件. O_WRONLY:以只寫的方式打開文件. O_RDWR:以讀寫的方式打開文件. O_APPEND:以追加的方式打開文件. O_CREAT:創建一個文件. O_EXEC:如果使用了O_CREAT而且文件已經存在,就會發生一個錯誤. O_NOBLOCK:以非阻塞的方式打開一個文件. O_TRUNC:如果文件已經存在,則刪除文件的內容. 前面三個標志只能使用任意的一個.如果使用了O_CREATE標志,那么我們要使用open的第二種形式.還要指定mode標志,用來表示文件的訪問權限.mode可以是以下情況的組合. ----------------------------------------------------------------- S_IRUSR????????用戶可以讀?????S_IWUSR????????用戶可以寫 S_IXUSR????????用戶可以執行???S_IRWXU????????用戶可以讀寫執行 ----------------------------------------------------------------- S_IRGRP????????組可以讀???????S_IWGRP????????組可以寫 S_IXGRP????????組可以執行?????S_IRWXG????????組可以讀寫執行 ----------------------------------------------------------------- S_IROTH?????????其他人可以讀????S_IWOTH?????????其他人可以寫 S_IXOTH?????????其他人可以執行??S_IRWXO?????????其他人可以讀寫執行 ----------------------------------------------------------------- S_ISUID????????設置用戶執行ID??S_ISGID???????????????設置組的執行ID ----------------------------------------------------------------- 我們也可以用數字來代表各個位的標志.Linux總共用5個數字來表示文件的各種權限. 00000.第一位表示設置用戶ID.第二位表示設置組ID,第三位表示用戶自己的權限位,第四位表示組的權限,最后一位表示其他人的權限. 每個數字可以取1(執行權限),2(寫權限),4(讀權限),0(什么也沒有)或者是這幾個值的和. 比如我們要創建一個用戶讀寫執行,組沒有權限,其他人讀執行的文件.設置用戶ID位那么我們可以使用的模式是--1(設置用戶ID)0(組沒有設置)7(1+2+4)0(沒有權限,使用缺省)5(1+4)即10705: open("temp",O_CREAT,10705); 如果我們打開文件成功,open會返回一個文件描述符.我們以后對文件的所有操作就可以對這個文件描述符進行操作了. 當我們操作完成以后,我們要關閉文件了,只要調用close就可以了,其中fd是我們要關閉的文件描述符. 文件打開了以后,我們就要對文件進行讀寫了.我們可以調用函數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是我們要寫入文件內容或讀出文件內容的內存地址.count是我們要讀寫的字節數. 對于普通的文件read從指定的文件(fd)中讀取count字節到buffer緩沖區中(記住我們必須提供一個足夠大的緩沖區),同時返回count. 如果read讀到了文件的結尾或者被一個信號所中斷,返回值會小于count.如果是由信號中斷引起返回,而且沒有返回數據,read會返回-1,且設置errno為EINTR.當程序讀到了文件結尾的時候,read會返回0. write從buffer中寫count字節到文件fd中,成功時返回實際所寫的字節數. 下面我們學習一個實例,這個實例用來拷貝文件. #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); } /*??????創建目的文件???*/ 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); } /*??????以下代碼是一個經典的拷貝文件的代碼????*/ while(bytes_read=read(from_fd,buffer,BUFFER_SIZE)) { /*??????一個致命的錯誤發生了???*/ if((bytes_read==-1)&&(errno!=EINTR)) break; else if(bytes_read>0) { ptr=buffer; while(bytes_write=write(to_fd,ptr,bytes_read)) { /*??????一個致命錯誤發生了?????*/ if((bytes_write==-1)&&(errno!=EINTR))break; /*??????寫完了所有讀的字節?????*/ else if(bytes_write==bytes_read) break; /*??????只寫了一部分,繼續寫????*/ else if(bytes_write>0) { ptr+=bytes_write; bytes_read-=bytes_write; } } /*??????寫的時候發生的致命錯誤?*/ if(bytes_write==-1)break; } } close(from_fd); close(to_fd); exit(0); } 2。文件的各個屬性 文件具有各種各樣的屬性,除了我們上面所知道的文件權限以外,文件還有創建時間,大小等等屬性. 有時侯我們要判斷文件是否可以進行某種操作(讀,寫等等).這個時候我們可以使用access函數. #include int access(const char *pathname,int mode); pathname:是文件名稱,mode是我們要判斷的屬性.可以取以下值或者是他們的組合. R_OK文件可以讀,W_OK文件可以寫,X_OK文件可以執行,F_OK文件存在.當我們測試成功時,函數返回0,否則如果有一個條件不符時,返回-1. 如果我們要獲得文件的其他屬性,我們可以使用函數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;????????/*?設備???*/ ino_t??????????st_ino;????????/*?節點???*/?? mode_t?????????st_mode;???????/*?模式???*/ nlink_t????????st_nlink;??????/*?硬連接?*/ uid_t??????????st_uid;????????/*?用戶ID */ gid_t??????????st_gid;????????/*?組ID???*/ dev_t??????????st_rdev;???????/*?設備類型?*/ off_t??????????st_off;????????/*?文件字節數?*/ unsigned long?st_blksize;????/*?塊大小?*/ unsigned long??st_blocks;?????/*?塊數???*/ time_t?????????st_atime;??????/*?最后一次訪問時間?*/ time_t?????????st_mtime;??????/*?最后一次修改時間?*/ time_t?????????st_ctime;??????/*?最后一次改變時間(指屬性) */ }; stat用來判斷沒有打開的文件,而fstat用來判斷打開的文件.我們使用最多的屬性是st_mode.通過著屬性我們可以判斷給定的文件是一個普通文件還是一個目錄,連接等等.可以使用下面幾個宏來判斷. S_ISLNK(st_mode):是否是一個連接.S_ISREG是否是一個常規文件.S_ISDIR是否是一個目錄S_ISCHR是否是一個字符設備.S_ISBLK是否是一個塊設備S_ISFIFO是否 是一個FIFO文件.S_ISSOCK是否是一個SOCKET文件.?我們會在下面說明如何使用這幾個宏的. 3。目錄文件的操作 在我們編寫程序的時候,有時候會要得到我們當前的工作路徑。C庫函數提供了getcwd來解決這個問題。 #include char *getcwd(char *buffer,size_t size); 我們提供一個size大小的buffer,getcwd會把我們當前的路徑考到buffer中.如果buffer太小,函數會返回-1和一個錯誤號. Linux提供了大量的目錄操作函數,我們學習幾個比較簡單和常用的函數. #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很容易就是我們創建一個目錄,opendir打開一個目錄為以后讀做準備.readdir讀一個打開的目錄.rewinddir是用來重讀目錄的和我們學的rewind函數一樣.closedir是關閉一個目錄.telldir和seekdir類似與ftee和fseek函數. 下面我們開發一個小程序,這個程序有一個參數.如果這個參數是一個文件名,我們輸出這個文件的大小和最后修改的時間,如果是一個目錄我們輸出這個目錄下所有文件的大小和修改時間. #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);> | <<等等重定向操作符.在這些過濾和重 定向程序當中,都用到了管道這種特殊的文件.系統調用pipe可以創建一個管道. #include int pipe(int fildes[2]); pipe調用可以創建一個管道(通信緩沖區).當調用成功時,我們可以訪問文件描述符fildes[0],fildes[1].其中fildes[0]是用來讀的文件描述符,而fildes[1]是用來寫的文件描述符. 在實際使用中我們是通過創建一個子進程,然后一個進程寫,一個進程讀來使用的. 關于進程通信的詳細情況請查看進程通信 #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); } } 為了實現重定向操作,我們需要調用另外一個函數dup2. #include int dup2(int oldfd,int newfd); dup2將用oldfd文件描述符來代替newfd文件描述符,同時關閉newfd文件描述符.也就是說, 所有向newfd操作都轉到oldfd上面.下面我們學習一個例子,這個例子將標準輸出重定向到一個文件. #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); } 好了,文件一章我們就暫時先討論到這里,學習好了文件的操作我們其實已經可以寫出一些比較有用的程序了.我們可以編寫一個實現例如dir,mkdir,cp,mv等等常用的文件操作命令了. 想不想自己寫幾個試一試呢? 前言:Linux下的時間概念 這一章我們學習Linux的時間表示和計算函數 時間的表示 時間的測量 計時器的使用 1。時間表示?????在程序當中,我們經常要輸出系統當前的時間,比如我們使用date命令的輸出結果.這個時候我們可以使用下面兩個函數 #include time_t??time(time_t *tloc); char????*ctime(const time_t *clock); time函數返回從1970年1月1日0點以來的秒數.存儲在time_t結構之中.不過這個函數的返回值對于我們來說沒有什么實際意義.這個時候我們使用第二個函數將秒數轉化為字符串.?這個函數的返回類型是固定的:一個可能值為. Thu Dec 7 14:58:59 2000?這個字符串的長度是固定的為26 2。時間的測量?????有時候我們要計算程序執行的時間.比如我們要對算法進行時間分析.這個時候可以使用下面這個函數. #include int gettimeofday(struct timeval *tv,struct timezone *tz); strut timeval { long????tv_sec;????????/*??????秒數???????????*/ long????tv_usec;???????/*??????微秒數?????????*/ }; gettimeofday將時間保存在結構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函數得到間隔計時器的時間值.保存在value中?setitimer函數設置間隔計時器的時間值為newval.并將舊值保存在oldval中. which表示使用三個計時器中的哪一個. itimerval結構中的it_value是減少的時間,當這個值為0的時候就發出相應的信號了.?然后設置為it_interval值. #include #include #include #include #include #define????????PROMPT??"時間已經過去了兩秒鐘\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); }

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。