標準io和文件io提茁,套接字高級io

概念

  • 文件I/O稱之為不帶緩存的IO(unbuffered I/O)淹禾。不帶緩存指的是每個read,write都調用內核中的一個系統(tǒng)調用茴扁。也就是一般所說的低級I/O——操作系統(tǒng)提供的基本IO服務铃岔,與os綁定,特定于linix或unix平臺峭火。但是這個不帶緩存表示用戶不緩存德撬,不代表操作系統(tǒng)沒有緩存。
  • 標準io是ANSI C建立的一個標準I/O模型躲胳,是一個標準函數(shù)包和stdio.h頭文件中的定義蜓洪,具有一定的可移植性。標準I/O庫處理很多細節(jié)坯苹。例如緩存分配隆檀,以優(yōu)化長度執(zhí)行I/O等。標準的I/O提供了三種類型的緩存粹湃。
    • 全緩存:當填滿標準I/O緩存后才進行實際的I/O操作恐仑。
    • 行緩存:當輸入或輸出中遇到新行符時,標準I/O庫執(zhí)行I/O操作为鳄。
    • 不緩存:stderr就是了裳仆。

區(qū)別

  • 文件I/O 又稱為低級磁盤I/O,遵循POSIX相關標準孤钦。
  • 標準I/O被稱為高級磁盤I/O歧斟,遵循ANSI C相關標準
  • 通過文件I/O讀寫文件時,每次操作都會執(zhí)行相關系統(tǒng)調用偏形。這樣處理的好處是直接讀寫實際文件静袖,壞處是頻繁的系統(tǒng)調用會增加系統(tǒng)開銷,標準I/O可以看成是在文件I/O的基礎上封裝了緩沖機制俊扭。先讀寫緩沖區(qū)队橙,必要時再訪問實際文件,從而減少了系統(tǒng)調用的次數(shù)
  • 文件I/O中用文件描述符表現(xiàn)一個打開的文件捐康,可以訪問不同類型的文件如普通文件仇矾、設備文件和管道文件等。而標準I/O中用FILE(流)表示一個打開的文件解总,通常只用來訪問普通文件贮匕。
API區(qū)別:

文件io

#include <fcntl.h>
#include <unistd.h>
int open(const char *pathname, int oflag, ... mode_t mode);
#成功返回文件描述符, 失敗返回-1 
int close(int filedes);
#成功返回0倾鲫, 失敗返回-1
off_t lseek(int filedes, off_t offset, int whence);
#成功返回新的文件偏移量粗合,出錯返回-1 
ssize_t read(int filedes, void *buf, size_t nbytes);
#成功則返回讀取到的字節(jié)數(shù)萍嬉,若已到文件的結尾返回0乌昔,出錯返回-1 
ssize_t write(int filedes, void *buf, size_t nbytes);
#成功則返回寫入的字節(jié)數(shù),出錯返回-1 

標準io

  • 除非引用終端設別壤追,否則系統(tǒng)默認流打開是全緩沖的磕道。
打開 
#include <stdio.h>
#fopen 打開一個指定的文件
FILE *fopen(const char *restrict pathname, const char *restrict type);
#freopen 在一個指定的流上打開一個文件,比如在標準輸出流上打開某文件
FILE *freopen(const char *restrict pathname, const char *restrict type, FILE *restrict fp);
#dopen 打開指定的文件描述符代表的文件行冰。常用于讀取管道或者其他特殊類型的文件溺蕉,因為這些文件不能直接用fopen打開。
FILE *dopen(int filedes, const char *type);
# 成功返回FILE類型指針悼做,出錯返回NULL 
# type 參數(shù)指定操作類型疯特,入讀寫,追加等等肛走。

關閉
#include <stdio.h>
int flose(FILE *fp);
# 成功返回0漓雅,出錯返回EOF 
每次一個字符的io
#include <stdio.h>

每次一個字符的IO流
輸入 
int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);
#上面三個函數(shù)的返回值為int,因為EOF常實現(xiàn)為-1朽色,返回int就能與之比較 

判斷出錯或者結束 
int ferror(FILE *fp);
int feof(FILE *fp);
void clearerr(FILE *fp); 
#清除error或者eof標志 

輸出
int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);

每次一行的IO流
#include <stdio.h>
#輸入
char *fgets(char *restrict buf, int n, FILE *restrict fp);
char *gets(char *buf);
#gets由于沒有指定緩沖區(qū)邻吞,所以有可能造成緩沖區(qū)溢出,要小心 

#輸出
int fputs(char *restrict buf, FILE *restrict fp);
int puts(const char *buf);

#格式化輸出IO流
printf 輸出到標準輸出
fprintf 輸出到指定流
sprintf 輸出到指定數(shù)組
snprintf 輸出到指定數(shù)組并在數(shù)組的尾端自動添加一個null字節(jié)

#格式化輸入IO流
scanf 從標準輸入獲取
fscanf 從指定流獲取
sscanf 從指定數(shù)組獲取

網(wǎng)絡高級io

#include <sys/socket.h>
ssize_t recv(int sockfd, void * buff, size_t nbytes, int flags);
    success return recv-byte-count, error return -1
ssize_t send(int sockfd, const void * buff, size_t nbytes, int flags);
    success return send-byte-count, error return -1
    flags:
        MSG_DONTROUTE, MSG_DONTWAIT, MSG_OOB, MSG_PEEK, MSG_WAITALL
 
/* if system support MSG_WAITALL */
#define readn(fd, ptr, n) recv(fd, ptr, n, MSG_WAITALL)
 
#include <sys/uio.h>
ssize_t readv(int fileds, const struct iovec * iov, int iovcnt);
    success return total-read-byte-count, error return -1
ssize_t writev(int fileds, const struct iovec * iov, int iovcnt);
    success return total-write-byte-count, error return -1
    struct iovec {
        void  * iov_base; /* starting address of buffer */
        size_t  iov_len;  /* size of buffer */
    };
 
#include <sys/socket.h>
ssize_t recvmsg(int sockfd, struct msghdr * msg, int flags);
    success return recv-byte-count, error return -1
ssize_t sendmsg(int sockfd, struct msghdr * msg, int flags);
    success return send-byte-count, error return -1
    struct msghdr {
        void         * msg_name;        /* protocol address */
        socklen_t      msg_namelen;     /* size of protocol address (val-ret)*/
        struct iovec * msg_iov;         /* scatter/gather array */
        int            msg_iovlen;      /* element-count in msg_iov */
        void         * msg_control;     /* ancillary data (cmsghdr struct) */
        socklen_t      msg_controllen;  /* length of ancillary data */
        int            msg_flags;       /* flags returned by recvmsg() */
        ...
    };
    flags:
        MSG_DONTROUTE, MSG_DONTWAIT, MSG_OOB, MSG_PEEK, MSG_WAITALL
    msg_flags:
        MSG_DONTROUTE, MSG_DONTWAIT, MSG_OOB, MSG_PEEK, MSG_WAITALL
        MSG_BCAST, MSG_MCAST, MSG_TRUNC, MSG_CTRUNC, MSG_EOR, MSG_NOTIFICATION
    struct cmsghdr {
        socklen_t  cmsg_len;   /* length in bytes, including this structure */
        int        cmsg_level; /* originating protocol */
        int        cmsg_type;  /* protocol-specific type */
        /* followed by unsigned char cmsg_data[] */
    };
 
#include <sys/socket.h>
#include <sys/param.h> /* for ALIGN macro on many implementations */
struct cmsghdr * CMSG_FIRSTHDR(struct msghdr * mhdrptr);
struct cmsghdr * CMSG_NXTHDR(struct msghdr * mhdrptr, 
                             struct cmsghdr * cmsgptr);
unsigned char * CMSG_DATA(struct cmsghdr * cmsgptr);
 
unsigned int CMSG_LENGTH(unsigned int length);
unsigned int CMSG_SPACE(unsigned int length);
 
usage:
    struct msghdr    msg;
    struct cmsghdr * cmsgptr;
    /* fill in msg structure */
    /* call recvmsg() */
    for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; 
         cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
        if (cmsgptr->cmsg_level == ... && 
            cmsgptr->cmsg_type == ...) {
            u_char * ptr = CMSG_DATA(cmsgptr);
            /* process data */
        }
    }
 
/dev/poll - interface:
#include <sys/devpoll.h>
struct dvpoll {
    struct pollfd * dp_fds;
    int             dp_nfds;
    int             dp_timeout;
};
 
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
int kqueue(void);
int kevent(int kq, const struct kevent * changelist, int nchanges, 
           struct kevent * eventlist, int nevents, 
           const struct timespec * timeout);
void EV_SET(struct kevent * kev, uintptr_t ident, short filter, 
            u_short flags, u_int fflags, intptr_t data, void * udata);
    struct kevent {
        uintptr_t  ident;
        short      filter;
        u_short    flags;
        u_int      fflags;
        intptr_t   data;
        void     * udata;
    };
    flags:
        EV_ADD,     EV_CLEAR,  EV_DELETE,  (value)
        EV_DISABLE, EV_ENABLE, EV_ONESHOT, (value)
        EV_EOF,     EV_ERROR               (result)
    filter:
        EVFILT_AIO, EVFILT_PROC, EVFILT_READ, EVFILT_SIGNAL, 
        EVFILT_TIMER, EVFILT_VNODE, EVFILT_WRITE



參考連接:
上下文切換詳解
Unix/Linux中的read和write函數(shù)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末葫男,一起剝皮案震驚了整個濱河市抱冷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梢褐,老刑警劉巖旺遮,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盈咳,居然都是意外死亡趣效,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門猪贪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跷敬,“玉大人,你說我怎么就攤上這事∥骺” “怎么了斤寇?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拥褂。 經常有香客問我娘锁,道長,這世上最難降的妖魔是什么饺鹃? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任莫秆,我火速辦了婚禮,結果婚禮上悔详,老公的妹妹穿的比我還像新娘镊屎。我一直安慰自己,他們只是感情好茄螃,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布缝驳。 她就那樣靜靜地躺著,像睡著了一般归苍。 火紅的嫁衣襯著肌膚如雪用狱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天拼弃,我揣著相機與錄音夏伊,去河邊找鬼。 笑死吻氧,一個胖子當著我的面吹牛溺忧,可吹牛的內容都是我干的。 我是一名探鬼主播医男,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼砸狞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了镀梭?” 一聲冷哼從身側響起刀森,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎报账,沒想到半個月后研底,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡透罢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年榜晦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羽圃。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡乾胶,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情识窿,我是刑警寧澤斩郎,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站喻频,受9級特大地震影響缩宜,放射性物質發(fā)生泄漏。R本人自食惡果不足惜甥温,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一锻煌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姻蚓,春花似錦宋梧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肛著。三九已至圆兵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間枢贿,已是汗流浹背殉农。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留局荚,地道東北人超凳。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像耀态,于是被迫代替她去往敵國和親轮傍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內容

  • feisky云計算首装、虛擬化與Linux技術筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,827評論 0 5
  • 第三章 文件i/o 3.1引言 不帶緩沖的io(unix系統(tǒng)在內核中設有緩沖區(qū)创夜,這個不帶緩沖意思是用戶不自己緩沖)...
    m風滿樓閱讀 991評論 0 0
  • 1,tableview點擊選中效果仙逻,放開點擊后選中效果消失驰吓。只需重寫tableview的delegate方法 2,...
    keking閱讀 533評論 0 0
  • 01 2017年高三畢業(yè)的那個夏天系奉,從6月9號到9月1號檬贰,差不多三個月的時間,現(xiàn)在回憶起來是又遙遠又模糊的昨天了缺亮。...
    炸雞腿我都吃了閱讀 434評論 4 6
  • 巴菲特的一生充滿了傳奇和秘密翁涤。 聽說過巴菲特的人都知道他有幾個標簽,股神,世界首富葵礼,投資家限书。 但這些標簽,都掩蓋了...
    核聚閱讀 1,364評論 0 1