天天看點

UNIX基礎知識之輸入和輸出

一、檔案描述符

  檔案描述符(file descriptor)通常是一個小的非負整數,核心用它辨別一個特定程序正在通路的檔案。當核心打開一個已有檔案或建立一個新檔案時,它傳回一個檔案描述符。在讀、寫檔案時,就可以使用它。

二、标準輸入、标準輸出和标準出錯

  按慣例,每當運作一個新程式時,所有的shell都會為其打開三個檔案描述符:标準輸入(standard input)、标準輸出(standard output)以及标準出錯(standard error)。如果沒有做什麼特殊處理(如重定向),則這三個描述符都鍊向終端。

三、不用緩沖的I/O

  函數open、read、write、lseek以及close提供了不用緩沖的I/O。這些函數都使用檔案描述符。

  程式清單1-2 将标準輸入複制到标準輸出

[[email protected] unix_env_advance_prog]# cat prog1-2.c 
#include "apue.h"

#define BUFFSIZE        4096

int
main(void)
{
        int     n;
        char    buf[BUFFSIZE];

        while((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
                if(write(STDOUT_FILENO, buf, n) != n)
                        err_sys("write error");
        if(n < 0)
                err_sys("read error");

        exit(0);
}      

  頭檔案<unistd.h>(apue.h中包含了此頭檔案)及兩個常量STDIN_FILENO和STDOUT_FILENO是POSIX标準的一部分。該頭檔案包含了很多UNIX系統服務的函數原型。

  兩個常量STDIN_FILENO和STDOUT_FILENO定義在<unistd.h>頭檔案中,它們指定了标準輸入和标準輸出的檔案描述符。它們的典型值分别是0和1,但是考慮到可移植性,我們将使用新名字。

  read函數傳回讀得多位元組數,此值用作要寫的位元組數。當到達檔案尾端時,read傳回0,程式停止執行。如果發生了一個讀錯誤,read傳回-1.出錯時大多數系統函數傳回-1.

  prog1-2.c編譯成功後,以下列方式執行它:

[[email protected] unix_env_advance_prog]# ./prog1-2 > data      

  那麼,标準輸入是終端,标準輸出則重新定向至檔案data,标準出錯也是終端。如果此輸出檔案并不存在,那麼shell會建立它。該程式将使用者鍵入的各行複制至标準輸出,鍵入檔案結束字元(通常是Ctrl+D)時,則終止該次複制。

  若以下列方式執行該程式:

[[email protected] unix_env_advance_prog]# ./prog1-2 < infile > outfile      

  那麼名為infile檔案的内容複制到名為outfile的檔案中。

四、标準I/O

  标準I/O函數提供一種對不用緩沖I/O函數的帶緩沖的接口。使用标準I/O函數可以無需擔心如何選取最佳的緩沖區大小,例如prog1-2中的BUFFSIZE常量的大小。使用标準I/O函數的另一個優點是簡化了對輸入行的處理(常常發生在UNIX的應用中)。例如,fgets函數讀一完整的行,而read函數讀指定位元組數。

  我們最熟悉的标準I/O函數是printf。在調用printf的程式中,總是包括<stdio.h>,該頭檔案包括了所有标準I/O函數的原型。

  程式清單1-3 用标準I/O将标準輸入複制到标準輸出

[[email protected] unix_env_advance_prog]# cat prog1-3.c 
#include "apue.h"

int
main(void)
{
        int     c;

        while((c = getc(stdin)) != EOF)
                if(putc(c, stdout) == EOF)
                        err_sys("output error");
        if(ferror(stdin))
                err_sys("input error");
        exit(0);
}      

  函數getc一次讀一個字元,然後函數putc将此字元寫到标準輸出。讀到輸入的最後1個位元組時,getc傳回常量EOF,該常量在<stdio.h>中定義。标準輸入/标準輸出常量stdin和stdout也定義在頭檔案<stdio.h>中,它們分别表示标準輸入和标準輸出檔案。

本篇博文内容摘自《UNIX環境進階程式設計》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。