国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(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庫(kù)由ISO C標(biāo)準(zhǔn)說明,由各個(gè)操作系統(tǒng)實(shí)現(xiàn)
  • 標(biāo)準(zhǔn)I/O庫(kù)處理很多細(xì)節(jié),如緩沖區(qū)分配、以優(yōu)化的塊長(zhǎng)度執(zhí)行I/O等。這些處理使用戶不必?fù)?dān)心如何使用正確的塊長(zhǎng)度,這使得它便于用于使用,但是如果不深入地了解I/O庫(kù)函數(shù)的操作,也會(huì)帶來一些問題。
2. 流和FILE對(duì)象
  • 第3章中,所有I/O函數(shù)都是圍繞文件描述符的;對(duì)于標(biāo)準(zhǔn)I/O庫(kù),它們的操作是圍繞流FILE *進(jìn)行的,稱其為文件指針
  • FILE對(duì)象通常是一個(gè)結(jié)構(gòu),它包括了標(biāo)準(zhǔn)I/O庫(kù)為管理該流需要的所有信息,包括用于實(shí)際I/O的文件描述符、指向用于該流緩沖區(qū)的指針、緩沖區(qū)的長(zhǎng)度、當(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庫(kù)提供緩沖的目的是盡可能減少使用read和write調(diào)用的次數(shù)。它對(duì)每個(gè)I/O流自動(dòng)地進(jìn)行緩沖管理,從而避免了應(yīng)用程序需要考慮這一點(diǎn)所帶來的麻煩。遺憾的是,標(biāo)準(zhǔn)I/O庫(kù)最令人迷惑的也是它的緩沖。

  • 標(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庫(kù)實(shí)施全緩沖。緩沖區(qū)可由標(biāo)準(zhǔn)I/O例程自動(dòng)地沖洗(flush),也可通過調(diào)用函數(shù)fflush沖洗一個(gè)流。
      • 術(shù)語(yǔ)flush有兩種意思:在標(biāo)準(zhǔn)I/O庫(kù)方面,flush(沖洗)意味著緩沖區(qū)中的內(nèi)容寫到磁盤上;在終端驅(qū)動(dòng)程序方面,flush(刷清)表示丟棄已存儲(chǔ)在緩沖區(qū)中的數(shù)據(jù)。
    2. 行緩沖。當(dāng)輸入或輸出中遇到換行符時(shí),標(biāo)準(zhǔn)I/O庫(kù)執(zhí)行I/O操作。當(dāng)流涉及一個(gè)終端時(shí),通常使用行緩沖。
      • 對(duì)于行緩沖有兩個(gè)限制:
        1. 只要填滿了緩沖區(qū),即使還沒遇到換行符,也進(jìn)行I/O操作;
        2. 任何時(shí)候只要通過標(biāo)準(zhǔn)I/O庫(kù)要求從(a)一個(gè)不帶緩沖的流,或者(b)一個(gè)行緩沖的流得到輸入數(shù)據(jù),那么就會(huì)flush所有行緩沖輸出流。
    3. 不帶緩沖。標(biāo)準(zhǔn)I/O庫(kù)不對(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è)長(zhǎng)度為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ū)及其長(zhǎng)度。若流帶緩沖而buf是NULL,則標(biāo)準(zhǔn)I/O庫(kù)將自動(dòng)地為該流分配適當(dāng)長(zhǎ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í),我們無(wú)法說明該文件的訪問權(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ā)表
主站蜘蛛池模板: 城口县| 永城市| 蕉岭县| 新营市| 杭州市| 全椒县| 大宁县| 新龙县| 马边| 昌黎县| 桐梓县| 托克托县| 开封市| 紫金县| 鹤壁市| 新建县| 长葛市| 福安市| 磐安县| 澎湖县| 抚远县| 昌黎县| 即墨市| 玛沁县| 宣城市| 宁安市| 原阳县| 兰考县| 公主岭市| 共和县| 西宁市| 大港区| 沈丘县| 双江| 屯门区| 寿阳县| 黄梅县| 广南县| 集安市| 吉隆县| 南雄市|