a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統(tǒng) > Unix > 正文

《Unix環(huán)境高級(jí)編程》讀書筆記 第5章-標(biāo)準(zhǔn)I/O流

2024-06-28 13:24:56
字體:
供稿:網(wǎng)友
《Unix環(huán)境高級(jí)編程》讀書筆記 第5章-標(biāo)準(zhǔn)I/O流1. 引言
  • 標(biāo)準(zhǔn)I/O庫由ISO C標(biāo)準(zhǔn)說明,由各個(gè)操作系統(tǒng)實(shí)現(xiàn)
  • 標(biāo)準(zhǔn)I/O庫處理很多細(xì)節(jié),如緩沖區(qū)分配、以優(yōu)化的塊長度執(zhí)行I/O等。這些處理使用戶不必?fù)?dān)心如何使用正確的塊長度,這使得它便于用于使用,但是如果不深入地了解I/O庫函數(shù)的操作,也會(huì)帶來一些問題。
2. 流和FILE對(duì)象
  • 第3章中,所有I/O函數(shù)都是圍繞文件描述符的;對(duì)于標(biāo)準(zhǔn)I/O庫,它們的操作是圍繞流FILE *進(jìn)行的,稱其為文件指針
  • FILE對(duì)象通常是一個(gè)結(jié)構(gòu),它包括了標(biāo)準(zhǔn)I/O庫為管理該流需要的所有信息,包括用于實(shí)際I/O的文件描述符、指向用于該流緩沖區(qū)的指針、緩沖區(qū)的長度、當(dāng)前在緩沖區(qū)中的字符數(shù)以及出錯(cuò)標(biāo)志等。

  • 標(biāo)準(zhǔn)I/O文件流可用于單字節(jié)或多字節(jié)(“寬”)字符集。

  • 流的定向決定了所讀、寫的字符是單字節(jié)還是多字節(jié)的。當(dāng)一個(gè)流最初被創(chuàng)建時(shí),它并沒有定向。若在為定向的流上使用一個(gè)多字節(jié)I/O函數(shù),則將流的定向設(shè)置為寬定向的;若在為定向的流上使用一個(gè)單字節(jié)I/O函數(shù),則將流的定向設(shè)置為字節(jié)定向的。
  1. #include <stdio.h>
  2. #include <wchar.h>
  3. int fwide(FILE *fp, int mode);
  4.   Returns: positive if stream is wide oriented, negative if stream is byte oriented, or 0 if stream has no orientation
  • 根據(jù)mode參數(shù)的不同字,fwide函數(shù)執(zhí)行不同的工作。
    1. mode為負(fù),則字節(jié)定向;
    2. mode為正,則寬定向;
    3. mode為0,則不設(shè)置流的定向,fwide返回標(biāo)識(shí)該流定向的值
  • 注意,fwide并不改變已定向流的定向
3. 標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤
  • 3個(gè)標(biāo)準(zhǔn)I/O流通過預(yù)定義文件指針(即FILE *) stdin、stdout、stderr加以引用。
4. 緩沖
  • 標(biāo)準(zhǔn)I/O庫提供緩沖的目的是盡可能減少使用read和write調(diào)用的次數(shù)。它對(duì)每個(gè)I/O流自動(dòng)地進(jìn)行緩沖管理,從而避免了應(yīng)用程序需要考慮這一點(diǎn)所帶來的麻煩。遺憾的是,標(biāo)準(zhǔn)I/O庫最令人迷惑的也是它的緩沖。

  • 標(biāo)準(zhǔn)I/O提供了以下3種類型的緩沖:

    1. 全緩沖。在填滿標(biāo)準(zhǔn)I/O緩沖區(qū)后才進(jìn)行實(shí)際I/O操作。對(duì)于駐留在磁盤上的文件通常由標(biāo)準(zhǔn)I/O庫實(shí)施全緩沖。緩沖區(qū)可由標(biāo)準(zhǔn)I/O例程自動(dòng)地沖洗(flush),也可通過調(diào)用函數(shù)fflush沖洗一個(gè)流。
      • 術(shù)語flush有兩種意思:在標(biāo)準(zhǔn)I/O庫方面,flush(沖洗)意味著緩沖區(qū)中的內(nèi)容寫到磁盤上;在終端驅(qū)動(dòng)程序方面,flush(刷清)表示丟棄已存儲(chǔ)在緩沖區(qū)中的數(shù)據(jù)。
    2. 行緩沖。當(dāng)輸入或輸出中遇到換行符時(shí),標(biāo)準(zhǔn)I/O庫執(zhí)行I/O操作。當(dāng)流涉及一個(gè)終端時(shí),通常使用行緩沖。
      • 對(duì)于行緩沖有兩個(gè)限制:
        1. 只要填滿了緩沖區(qū),即使還沒遇到換行符,也進(jìn)行I/O操作;
        2. 任何時(shí)候只要通過標(biāo)準(zhǔn)I/O庫要求從(a)一個(gè)不帶緩沖的流,或者(b)一個(gè)行緩沖的流得到輸入數(shù)據(jù),那么就會(huì)flush所有行緩沖輸出流。
    3. 不帶緩沖。標(biāo)準(zhǔn)I/O庫不對(duì)字符進(jìn)行緩沖存儲(chǔ)。如fputs函數(shù)。標(biāo)準(zhǔn)錯(cuò)誤流stderr通常是不帶緩沖的。
  • ISO C要求下列緩沖特征:

    • 當(dāng)且僅當(dāng)標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出并不指向交互式設(shè)備時(shí),它們才是全緩沖的
    • 標(biāo)準(zhǔn)錯(cuò)誤決不會(huì)是全緩沖的
  • 很多系統(tǒng)默認(rèn)使用下列類型的緩沖:

    • 標(biāo)準(zhǔn)錯(cuò)誤是不帶緩沖的
    • 若是指向終端設(shè)備的流,則是行緩沖的;否則是全緩沖的
  1. #include <stdio.h>
  2. void setbuf(FILE *restrict fp, char *restrict buf );
  3. // 使用該函數(shù)打開或關(guān)閉緩沖機(jī)制。參數(shù)buf必須指向一個(gè)長度為BUFSIZ的緩沖區(qū);或?yàn)镹ULL以關(guān)閉緩沖
  4. int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);
  5. Returns: 0 if OK, nonzero on error
  • 上面兩個(gè)函數(shù)必須在流被打開后,且對(duì)流執(zhí)行任何一個(gè)其他操作之前調(diào)用
  • mode參數(shù):_IOFBF全緩沖、_IOLBF行緩沖、_IONBF不帶緩沖
  • 如果指定全緩沖或行緩沖,則buf和size可選擇地指定一個(gè)緩沖區(qū)及其長度。若流帶緩沖而buf是NULL,則標(biāo)準(zhǔn)I/O庫將自動(dòng)地為該流分配適當(dāng)長度的緩沖區(qū)。
  1. #include <stdio.h>
  2. int fflush(FILE *fp); // 若fp為NULL,則導(dǎo)致所有輸出流被沖洗
  3.   Returns: 0 if OK, EOF on error
5. 打開流
  • 下列3個(gè)函數(shù)打開一個(gè)標(biāo)準(zhǔn)I/O流
  1. #include <stdio.h>
  2. FILE *fopen(const char *restrict pathname, const char *restrict type);
  3. FILE *freopen(const char *restrict pathname, const char *restrict type, FILE *restrict fp);
  4. // 在一個(gè)指定的流上打開一個(gè)指定的文件,如若該流已經(jīng)打開,則先關(guān)閉該流
  5. FILE *fdopen(int fd, const char *type); // 取一個(gè)已有的文件描述符,并使一個(gè)標(biāo)準(zhǔn)的I/O流與該描述符相結(jié)合
  6.   All three return: file pointer if OK, NULL on error
  • 打開標(biāo)準(zhǔn)I/O流的type參數(shù)
  • 字符b,代表二進(jìn)制。但Unix內(nèi)核并不對(duì)文本文件和二進(jìn)制文件進(jìn)行區(qū)分
  • 注意:在指定w或a類型創(chuàng)建一個(gè)新文件時(shí),我們無法說明該文件的訪問權(quán)限位;而open和creat可以
  • 如果以讀和寫類型打開一個(gè)文件時(shí)(type中帶+號(hào)),具有下列限制:

    1. 如果中間沒有fflush、fseek、fsetpos或rewind,則在輸出的后面不能直接跟隨輸入
    2. 如果中間沒有fseek、fsetpos或rewind,或者一個(gè)輸入操作沒有到達(dá)文件尾端,則在輸入操作之后不能直接跟隨輸出
  • 打開一個(gè)標(biāo)準(zhǔn)I/O流的6種不同方式

  • 除非流引用終端設(shè)備,否則按系統(tǒng)默認(rèn),流被打開是全緩沖的。若流引用終端設(shè)備,則該流是行緩沖的。
  1. #include <stdio.h>
  2. int fclose(FILE *fp);
  3.   Returns: 0 if OK, EOF on error
  • 當(dāng)一個(gè)進(jìn)程正常終止時(shí)(調(diào)用exit或從main函數(shù)返回),則所有帶未寫緩沖數(shù)據(jù)的標(biāo)準(zhǔn)I/O流都被沖洗,所有打開的標(biāo)準(zhǔn)I/O流都被關(guān)閉。
6. 讀和寫流
  • 一旦打開了流,可在3種不同類型的非格式化I/O中進(jìn)行選擇,對(duì)其進(jìn)行讀、寫操作

    1. 每次一個(gè)字符的I/O
    2. 每次一行的I/O
    3. 直接I/O(二進(jìn)制I/O、面向記錄的I/O、一次一個(gè)對(duì)象的I/O)
  • 在大多數(shù)實(shí)現(xiàn)中,為每個(gè)流在FILE對(duì)象中維護(hù)了兩個(gè)標(biāo)志:

    1. 出錯(cuò)標(biāo)志
    2. 文件結(jié)束標(biāo)志
  • 區(qū)分是出錯(cuò)還是到達(dá)文件尾端,因?yàn)檫@兩種情況下返回值相同

  1. #include <stdio.h>
  2. int ferror(FILE *fp);
  3. int feof(FILE *fp);
  4.   Both return: nonzero (true) if condition is true, 0 (false) otherwise
  5. void clearerr(FILE *fp); // 調(diào)用clearerr可以清除這兩個(gè)標(biāo)志
7. 每次一個(gè)字符的I/O
  • 輸入函數(shù)
  1. #include <stdio.h>
  2. int getc(FILE *fp); // 可被實(shí)現(xiàn)為宏,故參數(shù)不應(yīng)當(dāng)是具有副作用的表達(dá)式;返回值是int,因?yàn)槌A縀OF是-1
  3. int fgetc(FILE *fp); // 一定是個(gè)函數(shù)
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 中文字幕第90页 | 伊人久操 | 日本精品一区二区三区视频 | 国内久久精品 | 亚洲一区视频 | 亚洲欧美日韩另类精品一区二区三区 | 亚洲精品成人av | 亚洲成人一区二区三区 | 亚洲一区二区三区四区五区中文 | а_天堂中文最新版地址 | 色综合激情 | 在线久草| 中文字幕三区 | 欧美成人在线影院 | 国产精品成人免费一区二区视频 | 久久久久久久国产精品 | 国产亚洲欧美在线 | 日韩在线国产 | 三级黄色视频毛片 | 精品国产一区二区三区不卡蜜臂 | 97色干| 欧美日日干 | 亚洲精品一区二区三区蜜桃久 | 欧美性生活视频 | 久久久久久国产免费视网址 | 九九久久免费视频 | 懂色av中文一区二区三区天美 | 一区二区欧美在线 | 日本午夜在线 | 天天天天天天天天干 | 日韩电影专区 | 欧洲精品一区二区 | 91伊人| 亚洲精品三级 | 成人日韩视频 | av官网在线 | 久久久久久九九九九 | 久久精品123 | 精品视频在线观看一区二区三区 | 伊人激情网 | 高清三区 |