APUE 學習筆記(四) 標準I/O庫

1.流與FILE對象

unix I/O系統調用都是針對文件描述符的
標準C的I/O函數都是針對流(文件指針)的,咱們使用一個流與一個文件相關聯
 

2.緩衝

標準I/O庫提供緩衝的目的就是儘量減小read和write系統調用的使用次數
標準I/O提供三種類型的緩衝:
(1) 全緩衝:在填滿標準I/O緩衝區後才進行實際I/O操做,磁盤上的文件一般是全緩衝,第一次I/O操做時調用malloc得到須要使用的緩衝區
(2)行緩衝:輸入輸出遇到換行符時,標準I/O庫執行I/O操做。涉及終端時(標準輸入和標準輸出)一般使用行緩衝
                 標準I/O庫用來收集每一行的緩衝區的長度是固定的,只要填滿了緩衝區,就必定會進行I/O操做
(3)不帶緩衝:標準出錯流stderr一般是不帶緩衝的,這使得出錯信息能夠儘快顯示出來
setbuf  setvbuf
 
使用標準I/O的一個優勢就是無需考慮緩衝以及最佳I/O長度的選擇
 

3.二進制I/O

(1)讀或寫一個二進制數組,例如,將一個浮點數組的第2-5個元素寫至一個文件
float data[10];
fwrite(&data[2], sizeof(data[0]), 4, fp);

(2)讀或寫一個結構體數組

struct {
    short count;
    long  total;
    char  name[NAMESIZE];
} item;

fwrite(&item, sizeof(item), 1, fp);

 

4.測試I/O性能

  #include <unistd.h>
  #include <fcntl.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <assert.h>
  
  #define BUFSIZE 1
  //#define BUFSIZE 8
  //#define BUFSIZE 64
  //#define BUFSIZE 256
  //#define BUFSIZE 1024
  //#define BUFSIZE 4096
  //#define BUFSIZE 9182
  
int main(int argc, char* argv[])
  {
    char buf[BUFSIZE];
    int nbytes = 0;
  /* unix read version */
      /*
      while ((nbytes = read(STDIN_FILENO, buf, BUFSIZE)) > 0) {
          if (write(STDOUT_FILENO, buf, nbytes) != nbytes) {
              fprintf(stderr, "write error\n");
          }
      }
      if (nbytes< 0) {
          fprintf(stderr, "read error\n");
      }
      */
  
      /* std c I/O version */
      int c;
      while ((c = fgetc(stdin)) != EOF) {
          if (fputc(c, stdout) == EOF) {
              fprintf(stderr, "fputc error\n");
          }
      }
      if (ferror(stdin)) {
          fprintf(stderr, "fgetc error\n");
      }
  
      return 0;
  }

  

咱們查看程序的測試文本: stat test.txt函數

得知:該測試文件爲 259,546,640Byte, I/O塊大小爲 4096字節性能

BUFSIZE 用戶CPU時間 系統CPU時間 時鐘時間 系統調用數
1 30.302 555.702 588.962 259,546,640
8 3.672 71.468 75.741 32,443,330
64 0.460 9.165 9.877 4,055,417
256 0.108 2.600 3.011 1,013,854
1024 0.052 1.020 1.889 253,464
4096 0.016 0.512 1.649 63,366
9182 0.000 0.596 1.735 31,683
fgetc fputc 7.604 0.380 8.001  
 從上表能夠看出:

(1) BUFSIZE直接決定了 系統調用數,因此使用unix I/O的關鍵在於選取最合適的緩衝區長度測試

(2)當BUFSIZE等於 文件 I/O塊大小時,系統CPU時間出現最小值,繼續增長緩衝區長度對此時間幾乎沒有影響spa

(3)fgetc fputc標準I/O自行管理緩衝區,可是其時間都大於 unix I/O最佳緩衝區時的時間值,使用標準I/O庫時,系統會自動選取一個最佳I/O長度unix

通常依據文件的I/O塊大小值,可是由於標準I/O的內部緩衝 和 unix I/O最佳緩衝區長度相等時,標準I/O庫中有一個 外存文件==> FILE內部緩衝 ==> 應用緩衝,指針

而Unix I/O 是直接 外存文件 ==> 應用緩衝, 二者雖然系統調用數相同,可是 標準I/O多了緩衝的操做,因此效率較低code

相關文章
相關標籤/搜索