linux中文件I/O操作(系統I/O)


我們都知道linux下所有設備都是以文件存在的,所以當我們需要用到這些設備的時候,首先就需要打開它們,下面我們來詳細了解一下文件I/O操作。

用到的文件I/O有以下幾個操作:打開文件、讀文件、寫文件、關閉文件等,對應用到的函數有:open、read、write、close、lseek(文件指針偏移)

文件描述符:對於內核而言,所有打開的文件都通過文件按描述符引用。文件描述符是一個非負整數。
                      當打開一個現有文件或者創建一個新文件時,內核向進程返回一個文件描述符。
                      當讀、寫一個文件時,使用open/creat返回的文件描述符標識該文件,將其作為參數傳送給read或write。

linux系統下文件描述符0是標准輸入,1是標准輸出,2是標准出錯,所以一般打開文件的時候文件描述符都是從3開始。 這里read和write是不能格式化讀取和寫入,如果想了解文件怎么格式化讀取和寫入的話,可以看看我以前寫的一篇隨筆。

 

一、打開文件1)頭文件
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>2)函數原型    int open(const char *pathname, int flags);

      參數:
      a、pathname:打開或者創建的文件名字,如"text"
      
      b、 flags:
         O_RDONLY:只讀打開
         O_WRONLY:只寫打開
         O_RDWR:讀、寫打開
         O_CREAT:若此文件不存在則創建它,使用O_CREAT時后面要跟文件的訪問權限位,如O_CREAT,0777
         O_APPEND:每次寫時都追加到文件的尾端
         O_EXCL :如果同時指定了O_CREAT,而文件已經存在,則出錯,用此可以測試一個文件是否
                  存在,如果不存在,則創建此文件,這使測試和創建兩者成為一個原子操作
         O_DSYNC:使每次write等待物理I/O操作完成,但是如果該寫操作並不影響讀取剛寫入的
                  數據,則不需等待文件屬性被更新
         O_NONBLOCK :如果path引用的是一個FIFO、一個塊特殊文件或一個字符特殊文件,則
                      此選項為文件的本次打開操作和后續的I/O操作設置非阻塞方式
         O_NOCTTY:如果path引用的是  終端設備,則將該設備分配為此進程的控制終端
         O_SYNC:使每次write要等待物理I/O操作完成,包括有該write引起的文件屬性更新所需的I/O
         O_TRUNC:如果文件存在,並且是常規文件而且以讀寫或者只寫打開,則將其長度截斷為0,
                  如果文件是FIFO或終端設備文件,O_TRUNC標志被忽略,否則O_TRUNC不明確
         O_DIRECTORY:如果pathname引用的不是目錄,則出錯

(3)返回值:
     成功:文件描述符
     失敗:-1 二、讀取文件1)頭文件  #include <unistd.h>2)函數原型   ssize_t read(int fd, void *buf, size_t count);
     參數:
     a、fd:調用open后返回的文件描述符
     b、buf:用來存放從文件中讀到的數據的緩沖區
     c、count:讀取的字節數
     
(3)返回值:
     成功:讀到的字節數,如果讀到文件尾端,則返回0
     失敗:-1 三、寫數據1)頭文件 #include <unistd.h>2)函數原型   ssize_t write(int fd, const void *buf, size_t count);
     參數:
     a、fd:調用open后返回的文件描述符
     b、buf:從來存放數據的緩沖區
     c、count:寫入數據的字節數

(3)返回值:
     成功:返回已寫的字節數
     失敗:-1 四、關閉文件1)頭文件  #include <unistd.h>2)函數原型  int close(int fd);
     參數:
     a、fd:調用open后返回的文件描述符

  
五、文件偏移1)頭文件  #include <sys/types.h>
              #include <unistd.h>2)函數原型   off_t lseek(int fd, off_t offset, int whence);
      參數:
      a、fd:調用open后返回的文件描述符
      b、offset  和參數whence有關,通常設置為0 (according  to  thedirective whence as follows)
      c、whence:
         SEEK_SET: 將文件的偏移量設置為距文件開始處offset個字節
         SEEK_CUR:將文件的偏移量設置為其當前值加offset個字節,offset可為正或負
         SEEK_END: 將文件的偏移量設置為文件長度加offset,offset可為正或負
         
(3)返回值:
     成功:返回新的文件偏移量
     失敗:-1

 

下面是代碼:

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define PATHNAME "text.txt"
#define LENGTH 4096

void error(char *name) //錯誤提示
{
    perror(name);
    exit(1);
}

int main(int argc,char *argv[])
{
    
    int fd ; //存放文件描述符
    int size1; //讀操作時的返回值
    int size; //寫操作時的返回值
    int offset; //文件偏移量
        
    //打開文件
    /*O_REWR表示已讀寫權限打開文件,O_CREAT表示如果文件不存在則創建
    *創建的新文件的權限為0777,即是可讀可寫可執行,O_APPEND表示
    *寫入數據時從文件尾端寫入*/
    if((fd = open(PATHNAME,O_RDWR|O_CREAT|O_APPEND,0777)) == -1)       
    {
        error("open");
    }        
    
    
    char buf[LENGTH];
    bzero(buf,sizeof(buf));
    
    //從文件中讀取數據
    if((size1 = read(fd,buf,sizeof(buf))) == -1)
    {
        error("read");
    }
    
    printf("%s\n",buf);
  
  
   char buf1[LENGTH] = "小世界";
   //寫入數據到文件中
   if((size = write(fd,buf1,strlen(buf1))) == -1)
   {
       error("write");
   }

    char buf3[LENGTH] = "hello world";
    if((size = write(fd,buf3,strlen(buf3))) == -1)
    {
        error("write");
    }
    
    //因為寫入數據到文件中的時候已經把文件指針偏移到文件尾端了,所以要重新把文件指針偏移到文件頭,方便下面的讀操作
    if((offset = lseek(fd,0,SEEK_SET)) == -1)
    {
        error("lseek");
    }
    
    bzero(buf,sizeof(buf));
    if((size1 = read(fd,buf,sizeof(buf))) == -1)
    {
        error("read");
    }
    printf("%s\n",buf);
    
    //關閉文件
    close(fd);
    return 0;
}
View Code
  • 用cat命令打開文件
  • 終端輸出


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM