亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Unix > 正文

UNIX高級環境編程(7)標準IO函數庫

2024-06-28 13:21:44
字體:
來源:轉載
供稿:網友
UNIX高級環境編程(7)標準IO函數庫 - 二進制文件IO,流定位,創建臨時文件和內存流

1 二進制IO(Binary IO)

在前一篇我們了解了逐字符讀寫和逐行讀寫函數。

如果我們在讀寫二進制文件,希望以此讀寫整個文件內容,這兩個函數雖然可以實現,但是明顯會很麻煩且多次循環明顯效率很低。

為了應對這種場景,標準IO庫提供了fread和fwrite函數。

函數聲明:

#include <stdio.h>

size_t fread(void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);

size_t fwrite(const void *restrict ptr, size_t size size_t nobj, FILE *restrict fp);

函數用法;

a) 讀寫一個數組。

float data[10];

if (write(&data[2], sizeof(float), 4, fp) != 4)

? ? err_sys(“fwrite error");

本例中,從流fp中讀取4個float型數據填入到數組下表從2到5得位置中。

b) 讀寫一個結構體

struct {

? ? short ?count;

? ? long ? total;

? ? char ? name[NAMESIZE];

} item;

if (fwrite(&item, sizeof(item), 1, fp) != 1)

? ? err_sys(“fwrite error");

本例中,從fp讀取數據填入到一個結構體中。

?

上面兩例都可以認為是讀寫一個結構體的數組,參數size是結構體的長度,參數nobj是數組中要讀寫的元素的個數。

?

函數返回值:

兩個函數的返回值都是讀寫的元素個數。

對于讀函數,返回值可能會比nobj小,如果有異常拋出或者讀到了文件結尾。這時需要調用函數ferror或feof來判斷。

對于寫函數,返回值比nobj小,則一定是有異常拋出。

?

函數細節:

在上面的例子中,我們通過fwrite函數填充了一個結構體,那么如果讀寫不在一個系統中,那么結構體的內存布局可能并不相同,這對于現在的多系統互聯工作的場景下很常見。我們會在討論socket時回來繼續看這個問題,實際的解決方案就是在不同系統間讀寫二進制數據時使用相同的協議。

?

2 定位流(Positioning a Stream)

我們有三種方法對流進行定位:

  • 函數ftell和fseek。將文件的當前偏移位置存儲在long integer型變量中;
  • 函數ftello和fseeko。將文件的當前偏移量存儲在off_t型變量中;
  • 函數fgetpos和fsetpos。使用數據類型fpos_t記錄文件的當前偏移量。

?

ftell和fseek函數聲明:

#include <stdio.h>

long ftell(FILE* fp); ? ?// Returns:current file position indicator if OK, -1L on error

int fseek(FILE* fp, long offset, int whence); ? ? ? // Returns:0 if OK , -1 on error

void rewind(FILE* fp);

函數細節:

  • 二進制文件的偏移量是從文件開始到當前位置的字節數;
  • ftell函數返回當前文件的偏移位置;
  • fseek函數用來定位文件到指定偏移位置;
  • fseek函數的參數whence,用來設置計算偏移量的方法:SEEK_SET表示從文件開頭開始計算,SEEK_CUR表示從文件當前偏移位置開始計算,SEEK_END表示從文件結尾開始計算。
  • 對于一些非Unix操作系統,存儲文本文件的存儲格式會有所不同,當前文件偏移量無法通過字節數來表示,這種情況下,參數whence需要設置為SEEK_SET,并且offset只有兩個值可以使用:0,表示倒回文本開頭;另一個可用值為函數ftell的返回值。

?

ftello和fseeko函數聲明:

#include <stdio.h>

off_t ftello(FILE* fp); ? ? // Returns: current file position indicator if OK, (off_t) -1 on error

int fseeko(FILE* fp, off_t offset, int whence); ? ? /// Returns: 0 if OK, -1 on error

函數細節:

  • 這兩個函數和上面的ftell和fseek功能相同,只是返回值類型不是long,而改成了off_t,實現上可以讓off_t的表示范圍更大。

?

fgetpos和fsetpos函數聲明:

#include <stdio.h>

int fgetpos(FILE* restrict fp, fpos_t *restrict pos);

int fsetpos(FILE* fp, const fpos_t pos);

函數細節:

  • fgetpos函數保存當前文件偏移量到參數pos中
  • fgetpos得到的pos可以用來使用fsetpos設置當前文件偏移量到之前的位置。

?

3 格式化輸入輸出格式化輸出函數

有五個PRintf函數負責格式化輸出。

函數聲明:

#include <stdio.h>

int printf(const char *restrict format, ...);

int fprintf(FILE *restrict fp, const char *restrict format, ...);

int dprintf(int fd, const char *restrict format, ..);

? ? ? // All three return : number of characters output if OK , negative value if output error

int sprintf(char *resrict buf, const char *restrict format, ...);

? ? ? // Returns: number of characters stored in array if OK, negative value if encoding error

int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);

? ? ? // Returns: number of characters,that would have been stored in array if buffer was large enough, negative value if encoding error

函數細節:

  • printf輸出到標準輸出;
  • fprintf輸出到指定的流中;
  • dprintf輸出到指定的文件描述符中;
  • sprintf將格式化字符串寫入到指定的buffer數組中,自動在結尾處加上一個null結尾符,但是不計入返回值中,并且,sprintf在buffer不夠大時可能發生越界,因此需要使用者保證buffer足夠大;
  • snprintf防止越界,在springf的參數中增加了buffer的大小參數,所有越界寫入的字符都被忽略,如果返回值比buffer得長度要小,則說明輸出沒有被截斷。

?

格式化輸入函數

函數聲明:

#include <stdio.h>

int scanf(const char *restrict format, ...);

int fscanf(FILE *restrict fp, const char *restrict format, ...);

int sscanf(const char *restrict buf, const char *restrict format, ...);

函數細節:

  • format參數后面接得參數,包含存放讀入字符串的變量地址。

更多關于格式化輸入輸出的細節可以自己查詢Unix操作系統手冊。

?

4 從流中獲取文件描述符

函數聲明:

#include <stdio.h>

int fileno(FILE* fp); ? ? ? // Returns: the file descriptor associated with the stream

如果我們需要調用dup和fcntl,則需要調用該函數。

?

5 臨時文件(Temporary Files)

標準IO庫提供了兩個函數用于創建臨時文件。

函數聲明:

#include <stdio.h>

char* tempnam(char *ptr);

FILE* tmpfile(void);

函數細節:

  • 函數tmpnam生成一個字符串,該字符串為一個合法的路徑名,并且不和任何已存在的文件重復。
  • 函數tmpnam每次調用都生成不同的字符串,知道TMP_MAX次數。
  • 如果函數tempnam的參數ptr為NULL,則生成的路徑字符串存在內存靜態區,函數返回值為指向該路徑字符串的指針。如果隨后再次使用null參數調用tempnam,會覆蓋之前生成的字符串。
  • 如果函數tempnam的參數ptr不是NULL,那么生成的路徑字符串存在ptr指向的數組內,所以需要保證ptr指向的數組的長度至少為L_tmpnam。
  • 函數tmpfile函數創建一個臨時二進制文件(type wb+),程序終止或者該文件被關閉,則該文件自動被刪除。對于UNIX操作系統而言,生成一個二進制文件并沒有什么影響,因為內核并不區分文本文件還是二進制文件。

Example:

Code:

#include?"apue.h"

?

int

main(void)

{

? ??char? ? name[L_tmpnam], line[MAXLINE];

? ??FILE? ? *fp;

?

? ? printf("%s/n", tmpnam(NULL)); ? ? ??/* first temp name */

?

? ? tmpnam(name); ? ? ? ? ? ? ? ? ? ? ??/* second temp name */

? ? printf("%s/n", name);

?

? ??if?((fp = tmpfile()) ==?NULL) ? ? ??/* create temp file */

? ? ? ? err_sys("tmpfile error");

? ? fputs("one line of output/n", fp);??/* write to temp file */

? ? rewind(fp); ? ? ? ? ? ? ? ? ? ? ? ??/* then read it back */

? ??if?(fgets(line,?sizeof(line), fp) ==?NULL)

? ? ? ? err_sys("fgets error");

? ? fputs(line,?stdout);? ? ? ? ? ? ? ??/* print the line we wrote */

?

? ? exit(0);

}

?

在系統The Single UNIX Specification定義了另外兩個函數處理臨時文件:

函數聲明:

char* mkdtemp(char* template); ? ?// Returns: pointer to directory name if OK, NULL on error

int mkstemp(char* template); ? ?// Returns: file descriptor if OK, -1 on error

函數細節:

  • mkdtemp函數創建一個名字唯一的文件夾
  • mkstemp函數創建一個名字唯一的常規文件(regular file)
  • 命名規則為 template + 六位隨機字符

?

6 內存流(Memory Streams)

有的標準輸入輸出流并沒有對應打開的硬盤文件,所有操作都是與內存中buffer進行數據交換,這些流被叫做內存流(memory streams)。

函數聲明:

#include <stdio.h>

FILE* fmemopen(void *restrict buf, size_t size, const char *restrict type);

// Returns: stream pointer if OK, NULL on error

函數細節:

  • 參數buf指定使用的buffer,size為該buffer的大小,如果只指定size,而buf為null,那么fmemopen根據size的大小分配內存,由fmemopen分配的內存在流關閉時自動被釋放;
  • 參數type控制該流的功能.

?

7 總結

標準IO函數庫被大多數UNIX應用使用。

在使用的時候,注意哪里使用了buffer來處理,因為這是容易引起迷惑的地方。

?

?

參考資料:

《Advanced Programming in the UNIX Envinronment 3rd》

?


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲精品久久久久久777| 亚洲国产精品专区久久| 欧美一区二区影院| 欧美色另类天堂2015| 欧美亚洲成人xxx| 亚洲人a成www在线影院| 欧美精品videossex88| 久久久精品国产一区二区| 亚洲奶大毛多的老太婆| 中文字幕最新精品| 精品久久久国产| 久久久精品999| 美日韩丰满少妇在线观看| 欧美激情一级欧美精品| 亚洲天堂精品在线| 97视频在线看| 日韩欧美中文在线| 午夜精品久久久久久久99热| 欧美放荡办公室videos4k| 欧美成人午夜激情在线| 中文字幕精品久久久久| 日本免费在线精品| 国产免费观看久久黄| 亚洲欧美变态国产另类| 亚洲精品一区久久久久久| 亚洲国内精品视频| 亚洲女性裸体视频| 隔壁老王国产在线精品| 丝袜亚洲另类欧美重口| 精品偷拍一区二区三区在线看| 久久av中文字幕| 精品成人av一区| 亚洲一区二区三区在线免费观看| 欧美色欧美亚洲高清在线视频| 久久久精品久久久| 精品视频9999| 亚洲美女中文字幕| 最新亚洲国产精品| 日韩精品免费电影| 亚洲欧美国产高清va在线播| 国产精品久久久久久久久久久久久| 亚洲精品成人久久| 97av在线视频| 日韩欧美极品在线观看| 91在线高清视频| 亚洲精品视频在线观看视频| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲美女激情视频| 中文字幕免费国产精品| 日韩中文字幕视频在线观看| 日韩久久精品电影| 国产精品高清在线| 久久在线观看视频| 91综合免费在线| 久久男人资源视频| 日韩成人高清在线| 欧美性xxxx18| 久久的精品视频| 色偷偷av一区二区三区| 91欧美精品午夜性色福利在线| 日韩理论片久久| 亚洲大胆人体在线| 亚洲香蕉伊综合在人在线视看| 精品视频在线播放色网色视频| 亚洲国产成人精品久久久国产成人一区| 26uuu另类亚洲欧美日本一| 日韩中文字幕网| 日韩经典中文字幕在线观看| 国产日韩在线一区| 国产精品视频中文字幕91| 亚洲午夜未满十八勿入免费观看全集| 91麻豆国产语对白在线观看| 久久亚洲精品国产亚洲老地址| 亚洲r级在线观看| 国产精品欧美一区二区三区奶水| 亚洲成人av资源网| 欧美色道久久88综合亚洲精品| 日韩av在线免费观看| 午夜精品免费视频| 亚洲一区二区三区四区视频| www.欧美三级电影.com| 欧美性猛交xxxx免费看久久久| 欧美性感美女h网站在线观看免费| 国产精品黄页免费高清在线观看| 久久久国产精彩视频美女艺术照福利| 亚洲午夜久久久久久久| 91老司机在线| 欧美激情视频免费观看| 视频在线观看一区二区| 国产精品久久婷婷六月丁香| 国产成人拍精品视频午夜网站| 国产在线拍偷自揄拍精品| 日韩中文字幕av| 伊人一区二区三区久久精品| 亚洲欧美一区二区三区情侣bbw| 亚洲精品之草原avav久久| 日本精品久久中文字幕佐佐木| 久久久久久久久久国产| 日韩激情视频在线播放| 九九久久精品一区| 国产91热爆ts人妖在线| 九九热这里只有精品6| 中文字幕亚洲欧美日韩高清| 成人免费视频在线观看超级碰| 国产精品∨欧美精品v日韩精品| 亚洲精品wwww| 国产精品日韩专区| 欧美有码在线观看| 尤物99国产成人精品视频| 日韩一区二区三区在线播放| 亚洲网在线观看| 777777777亚洲妇女| 亚洲精品国产精品久久清纯直播| 精品久久在线播放| 日韩av男人的天堂| 精品国产乱码久久久久久婷婷| 成人亚洲欧美一区二区三区| 一区二区三区四区精品| 97精品久久久中文字幕免费| 欧美精品一区三区| 欧美久久精品一级黑人c片| 伊人一区二区三区久久精品| 日本久久91av| 亚洲精品一区二区久| 97精品欧美一区二区三区| 成人黄色在线免费| 日韩精品亚洲元码| 色偷偷av一区二区三区乱| 久久久精品2019中文字幕神马| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产精品久久久久久久久久久久久| 隔壁老王国产在线精品| 国产精品尤物福利片在线观看| 国产精品亚洲精品| 成人激情视频小说免费下载| 992tv成人免费视频| 国产成人精品国内自产拍免费看| 亚洲高清av在线| 亚洲成人精品视频| 国产欧美va欧美va香蕉在线| 日本电影亚洲天堂| 亚洲视频在线视频| 日韩中文字幕在线播放| 亚洲高清免费观看高清完整版| 久久国产视频网站| 欧美日韩国产限制| 国产成人激情视频| 在线丨暗呦小u女国产精品| 69国产精品成人在线播放| 原创国产精品91| 欧美美女18p| 久久好看免费视频| 91网在线免费观看| 成人国内精品久久久久一区| 精品久久久久久久久中文字幕| 97视频在线播放| 日韩在线视频线视频免费网站| 一道本无吗dⅴd在线播放一区| 精品福利视频导航| 亚洲精品一区在线观看香蕉| 国内外成人免费激情在线视频网站| 精品女厕一区二区三区| 色婷婷综合久久久久| 亚洲精品视频二区|