1. 程式人生 > >UNIX系統檔案IO函式

UNIX系統檔案IO函式

在一開始接觸到Linux的時候,我們經常接觸到的系統IO函式有下列這幾個
open()函式,write()函式,read()函式,lseek()函式,close()函式下面我們將逐個探究一下:open函式: 開啟或建立一個檔案
庫和函式原型:
#include<fcntl.h>
int open(const char* pathname,int flag, ... /*mode_t mode*/)我們將第三個引數寫為...,是因為ISO C用這種方法表明餘下的引數機器型別將根據具體的呼叫有所不同。
對於open函式,只有在建立新檔案的時候才會使用到第三個引數。
解析:返回值:
成功返回一個整型(int)的檔案描述符,這個檔案描述符可以看作是一個開啟檔案的鑰匙,凡是對檔案的操作都離不開它。
錯誤返回-1
這個檔案描述符一定是用最小的未使用的描述符數值,其中0,1,2分別是標準輸入stdin,標準輸出stdout和標準出錯輸出stderr
,所以我們在不修改或者關閉其中三個的情況下,打印出的第一個描述符數值一般是3引數:
pathname:要開啟或者建立的檔名。
flag    :開啟方式的選項,用下來一個或多個常量進行或|運算構成的flag引數。
 選項:O_RDONLY,  O_WRONLY, O_RDWR   這三個常量必須有且只能選一個
       O_CREAT:檔案不存在則建立
       O_TRUNC:若檔案存在,則把資料清零。
       上面這幾個是常用到的,其它的選項可以自行man瞭解。
這幾個常量對應數值O_RDONLY----0, O_WRONLY----1, O_RDWR----2, O_CREAT----4
使用它們 注意進行或|運算之後的結果。mode:它其實是一個8進位制數,說明你將要建立檔案的許可權
      例:0777則代表-rwxrwxrwxwrite函式:往開啟的檔案裡面寫資料
庫和函式原型:
#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);解析:
返回值:成功則返回已寫的位元組數,錯誤返回-1fd:   open函式返回的檔案描述符
buf:  要寫入資料的地址,通常是已宣告的字串的首地址
count:一次要寫幾個位元組,通常為strlen()個

程式碼塊:
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<string.h>
#include<stdio.h>
#include<sys/stat.h>
int main()
{
        int fd=open("./log",O_WRONLY|O_CREAT,775);//以只寫的形式建立mylog
        if(fd==-1)
        {
                perror("open fail!\n");
                return -1;
        }
        const char*msg="Hello Koma\n";
        int i=0;
        while(i<10)
        {
                write(fd,msg,strlen(msg));
                i++;
        }
 printf("%s\n",msg);
        close(fd);
}

執行結果截圖:
read函式:     從開啟的裝置或檔案中讀取資料。
庫和函式原型:
#include <unistd.h>   
ssize_t read(int fd, void *buf, size_t count); 
返回值:成功返回讀取的位元組數,出錯返回-1並設定errno,0表示檔案末端
 如果在調read之前已到達檔案末尾,則這次read返回0
 如果要求讀100個位元組,而離檔案末尾只有99個位元組,則read返回99,下一次再呼叫read返回0

引數: 可聯絡write函式記憶
fd: 檔案描述符
buf: 要讀資料的地址,通常是已宣告的字串的首地址
count 一次要讀多少個數據
舉個例子:在終端讀入並寫出
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
        char*buf[10];
        size_t st=read(STDIN_FILENO,buf,10);//STDIN標準輸入
        if(st<0)
        {
                printf("read fail!\n");
        }
        write(STDOUT_FILENO,buf,st);//標準輸出
        printf("\n");
        return 0;
}
執行結果:
lseek函式: 顯式地為一個開啟的檔案設定偏移量,通常讀寫操作都是從當前檔案偏移量處開始的,並使偏移量增加所讀寫的位元組數庫和函式原型:#include <unistd.h>
#include <sys/types.h>off_t lseek(int fd, off_t offset, int whence);返回值:成功返回新的檔案偏移量注意可能負數,出錯返回-1
 如果檔案 描述符引用的是一個管道,FIFO或者 網路套接字,則lseek返回-1,,並將error設定成ESPIPE
引數:
fd: 檔案描述符
offset 的含義取決於引數 whence
whence有三個選項:
 1. 如果 whence 是 SEEK_SET, 檔案偏移量將被設定為           0加上 offset。
 2. 如果 whence 是 SEEK_CUR,檔案偏移量將被設定為 當前值 加上 offset,offset 可以為正也可以為負。
 3. 如果 whence 是 SEEK_END,檔案偏移量將被設定為檔案長度加上 offset,offset 可以為正也可以為負。
注意:
lseek 僅將檔案偏移量保存於核心中,不會導致任何 I/O 操作。這個檔案偏移量將被用於之後的讀寫操作。檔案偏移量可以大於當前檔案長度,在這之上,對檔案的下一次寫操作就會在檔案中(原始檔末端到新開始的位置)構成空洞,並被讀成0,且檔案中的空洞並不佔用磁碟的記憶體空間程式碼塊:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
  {
      int fd=open("./fish",O_RDWR|O_CREAT,0777);
      if(fd<0)
      {
          perror("open");
          printf("open fail!");
          return -1;
      }
      char msg[100] = "this is msg\n";
      write(STDOUT_FILENO,msg,strlen(msg));//在標準輸出視窗寫資料
      write(fd,msg,12);//在新建立的fish裡面寫資料
      lseek(fd, 0,SEEK_SET);//把偏移量設定成0,要是把0換成strlen(msg)-->r=0;
      int r = read(fd,msg,100);//從開始出開始讀資料
      printf("r=%d\n", r);
      close(fd);
      return 0;
  }

執行結果:


close(fd)函式: 關閉這個已開啟的檔案,這個就沒什麼好說的了吧。。。上面大概就是我在學習系統IO函式的時候的一點小結,其實就是把握好這個檔案描述符就好了,引數這個東西用多了就熟練了。。