1. 程式人生 > >Linux系統程式設計——IO程式設計

Linux系統程式設計——IO程式設計

1.Linux檔案操作
  “一切皆檔案”是Linux系統的基本思想。Linux 提供的虛擬檔案系統為多種檔案系統和外設驅動提供了統一的介面,基於此類介面,可以實現檔案的新建、開啟(open)、讀(read)、寫(write)、關閉(close),及對隨機檔案的定位(lseek)。
  通常,一個程序開啟現有檔案或新建檔案時,系統會返回一個檔案描述符fd(file descriptor),指示特定的檔案,後面的讀寫、關閉檔案都通過此檔案描述符進行操作。無錯誤狀態下的檔案描述符是非負數,開啟檔案前應檢查該標識是否為非負數。
  一個程序執行時,都有一張自身的檔案描述符,即是開啟三個檔案:標準輸入、標準輸出和標準出錯處理。程式執行起來後,這三個檔案是預設開啟的。對應的巨集描述為如下。
  #define STDIN_FILENO   0 //標準輸入的檔案描述符
  #define STDOUT_FILENO  1 //標準輸出的檔案描述符
  #define STDERR_FILENO   2 //標準錯誤的檔案描述符

2.常用IO函式

2.1 open函式
函式原型:
  int open(const char *pathname, int flags, mode_t mode);
所需標頭檔案:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

函式功能:
  開啟檔案,檔案不存在時則建立一個檔案。
函式引數:
  pathname:被開啟檔名,包括檔案路徑;
  flags:開啟檔案的行為標識,如只讀、只寫、讀寫等;具體引數選擇標識及含義如下。
這裡寫圖片描述
  注意:
    1)前三個取值引數不可使用“|”,但可以與後面幾個取值引數進行“|”操作,進行選擇相應功能;
    2)以讀寫方式開啟只能用“O_RDWR”,不能用“O_REONLY|O_WRONLY”。
  mode:此引數只有在開啟的檔案不存時才有效,即是指定建立檔案時的使用者許可權。
這裡寫圖片描述


函式返回值:
  成功:開啟檔案描述符。
  失敗:-1。

2.2close函式
函式原型:
  int close(int fd);
所需標頭檔案:

#include<uniste.h>

函式功能:
  關閉已開啟的檔案。
函式引數:
  fd:檔案描述符,open函式的返回值。
函式返回值:
  成功:0。
  失敗:-1。

2.3read函式
函式原型:
  ssize_t read(int fd, void *addr, size_t count);
所需標頭檔案:

#include<unistd.h>

函式功能:
  讀取指定的資料到記憶體。
函式引數:
  fd:檔案描述符。
  addr:記憶體首地址,存放讀取返回資料。
  count:讀取的位元組數。
函式返回值:
  成功:實際讀取位元組數。
  失敗:-1。

2.4write函式
函式原型:
  ssize_t write(int fd, const void *addr, size_t count);
所需標頭檔案:

#include<unistd.h>

函式功能:
  向檔案寫入指定的資料。
函式引數:
  fd:檔案描述符。
  addr:資料緩衝區首地址。
  count:待寫資料位元組數。
函式返回值:
  成功:實際寫入的位元組數。
  失敗:-1。

2.5lseek函式
函式原型:
  off_t lseek(int fd,off_t offset,int whence)
所需標頭檔案:

#include<unistd.h>
#include<sys/types.h>

函式功能:
  指定檔案操作地址偏移量。
函式引數:
  fd:檔案描述符。
  offset:偏移量,每一讀寫操作所需要移動的距離,單位是位元組的數量,可正可負(向前移,向後移)。
  whence:當前位置基點,取值及含義如下。
這裡寫圖片描述
函式返回值:
  成功:當前檔案位置。
  失敗:-1。

3.程式設計例項

3.1例項1
  利用IO函式讀寫檔案。

#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    char *buf="Read and write test!";
    char buf_r[strlen(buf)+1];
    int fd,size,len;
    len = strlen(buf);
    buf_r[len] = '/0';
    //首先呼叫open 函式,並指定相應的許可權
    if ((fd = open("io_test0.txt", O_CREAT | O_TRUNC | O_RDWR,0666 ))<0)
    {
        perror("open:");
        exit(1);
    }
    else
        printf("open and create file:io_test0.txt %d  OK\n",fd);
    //呼叫write 函式,將buf 中的內容寫入到開啟的檔案中
    if ((size = write( fd, buf, len)) < 0)
    {
        perror("write:");
        exit(1);
    }
    else
        printf("write:%s OK\n",buf);
    // 呼叫lseek 函式將檔案指標移動到檔案開始8個位元組,並讀出餘下內容 
    lseek(fd, 8, SEEK_SET );
    if ((size = read( fd, buf_r, len-8))<0)
    {
        perror("read:");
        exit(1);
    }
    else
        printf("read form file:%s OK\n",buf_r);
    if ( close(fd) < 0 )
    {
        perror("close:");
        exit(1);
    }
    else
        printf("close io_test0.txt OK\n");
    return 0;
}

Linux下執行結果:
這裡寫圖片描述

3.2例項2
  利用IO函式實現Linux命令終端的複製(cp)命令。使用 open() 開啟原始檔,使用 read() 從檔案讀資料,使用 write() 向目標檔案寫資料。

#include <stdio.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  

int main(int argc, char *argv[])  
{  
    if((argc == 3) && (strcmp(argv[1], argv[2]) != 0))  
    {// 保證有 3 個引數,而且原始檔和目的檔名字不能一樣  

        int fd_src, fd_dest, ret;  

        //只讀方式開啟原始檔  
        fd_src = open(argv[1], O_RDONLY);   
        if(fd_src < 0)  
        {  
            perror("open argv[1]");  
            return -1;  
        }  

        // 新建目的檔案  
        fd_dest = open(argv[2], O_WRONLY|O_CREAT, 0755);  
        if(fd_dest < 0)  
        {  
            close(fd_src);  
            perror("open argv[2]");  
            return -1;  
        }     
        do  
        {  
            char buf[1024] = {0};  
            // 從原始檔讀取資料  
            ret = read(fd_src, buf, sizeof(buf));  

            // 把資料寫到目的檔案,注意最後一個引數,有多少寫多少  
            write(fd_dest, buf, ret);  
        }while(ret > 0);  

        // 關閉已開啟的檔案  
        close(fd_src);  
        close(fd_dest);  
    }     
    return 0;  
}  

Linux下執行結果:
這裡寫圖片描述

4.參考