在UNIX系統中,標準I/O庫最終都要調用文件I/O(read、write等)。每個標準I/O流都有一個與其相關聯的文件描述符,可以對一個流調用fileno函數以獲得其描述符。
注意,fileno不是ISO C標準部分,而是POSIX.1支持的擴展。
#include <stdio.h>int fileno( FILE *fp );返回值:與該流相關聯的文件描述符
如果要調用dup或fcntl等函數,則需要此函數。
為了了解你所使用的系統中標準I/O庫的實現,最好從頭文件<stdio.h>開始。從中可以看到:FILE對象是如何定義的、每個流標志的定義以及定義為宏的各個標準I/O例程(例如getc)。
程序清單5-3中的程序為三個標準流以及一個普通文件相關聯的流打印有關緩沖的狀態信息。
程序清單5-3 對各個標準I/O流打印緩沖狀態信息
[root@localhost apue]# cat PRog5-3.c#include "apue.h"void pr_stdio( const char *, FILE * );int main( void ){ FILE *fp; fputs( "enter any character/n", stdout ); if( getchar() == EOF ) err_sys( "getchar error" ); fputs( "one line to standard error/n", stderr ); pr_stdio( "stdin", stdin ); pr_stdio( "stdout", stdout ); pr_stdio( "stderr", stderr ); if(( fp = fopen("/etc/mtab", "r")) == NULL) err_sys("fopen error"); if(getc(fp) == EOF) err_sys("getc error"); pr_stdio("/etc/mtab", fp); exit(0);}voidpr_stdio(const char *name, FILE *fp){ printf("stream = %s, ", name); /* * The following is nonportable. */ if(fp->_IO_file_flags & _IO_UNBUFFERED) printf("unbuffered"); else if(fp->_IO_file_flags & _IO_LINE_BUF) printf("line buffered"); else /* if neither of above */ printf("fully buffered"); printf(", buffer size = %d/n", fp->_IO_buf_end - fp->_IO_buf_base);}
注意,在打印緩沖狀態信息之前,先對每個流執行I/O操作,第一個I/O操作通常就造成為該流分配緩沖。結構成員_IO_file_flags、_IO_buf_base、_IO_buf_end和常量_IO_UNBUFFERED、_IO_LINE_BUFFERED是由linux中的GNU標準I/O庫定義的。應當了解,其他UNIX系統可能會有不同的標準I/O庫實現。
如果運行程序清單5-3中的程序兩次,一次使三個標準流與終端相連接,另一次使它們重定向到普通文件,則所得結果是:
[root@localhost apue]# ./prog5-3 stdin、stdout和stderr都連至終端enter any character 鍵入換行符one line to standard errorstream = stdin, line buffered, buffer size = 4096stream = stdout, line buffered, buffer size = 4096stream = stderr, unbuffered, buffer size = 1stream = /etc/mtab, fully buffered, buffer size = 4096[root@localhost apue]# ./prog5-3 < /etc/termcap > std.out 2> std.err 三個流都重定向,再次運行該程序[root@localhost apue]# cat std.errone line to standard error[root@localhost apue]# cat std.outenter any characterstream = stdin, fully buffered, buffer size = 4096stream = stdout, fully buffered, buffer size = 4096stream = stderr, unbuffered, buffer size = 1stream = /etc/mtab, fully buffered, buffer size = 4096
從中可見,該系統的默認情況是:當標準輸入、輸出連至終端時,它們是行緩沖的。行緩沖的長度是4096字節。注意,這并沒有將輸入、輸出的行長限制為4096字節,這只是緩沖區的長度。如果要將8192字節的行寫到標準輸出,則要進行兩次write系統調用。當將這兩個流重定向到普通文件時,它們就變成是全緩沖的,其緩沖區長度是該文件系統優先選用的I/O長度(從stat結構中得到的st_blksize值)。從中也可看到,標準出錯如它所應該的那樣是非緩沖的,而普通文件按系統默認是全緩沖的。
本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。
新聞熱點
疑難解答