标准io和文件io,套接字高级io

概念

  • 文件I/O称之为不带缓存的IO(unbuffered I/O)。不带缓存指的是每个read,write都调用内核中的一个系统调用。也就是一般所说的低级I/O——操作系统提供的基本IO服务,与os绑定,特定于linix或unix平台。但是这个不带缓存表示用户不缓存,不代表操作系统没有缓存。
  • 标准io是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准I/O库处理很多细节。例如缓存分配,以优化长度执行I/O等。标准的I/O提供了三种类型的缓存。
    • 全缓存:当填满标准I/O缓存后才进行实际的I/O操作。
    • 行缓存:当输入或输出中遇到新行符时,标准I/O库执行I/O操作。
    • 不缓存:stderr就是了。

区别

  • 文件I/O 又称为低级磁盘I/O,遵循POSIX相关标准。
  • 标准I/O被称为高级磁盘I/O,遵循ANSI C相关标准
  • 通过文件I/O读写文件时,每次操作都会执行相关系统调用。这样处理的好处是直接读写实际文件,坏处是频繁的系统调用会增加系统开销,标准I/O可以看成是在文件I/O的基础上封装了缓冲机制。先读写缓冲区,必要时再访问实际文件,从而减少了系统调用的次数
  • 文件I/O中用文件描述符表现一个打开的文件,可以访问不同类型的文件如普通文件、设备文件和管道文件等。而标准I/O中用FILE(流)表示一个打开的文件,通常只用来访问普通文件。
API区别:

文件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);
#成功则返回读取到的字节数,若已到文件的结尾返回0,出错返回-1 
ssize_t write(int filedes, void *buf, size_t nbytes);
#成功则返回写入的字节数,出错返回-1 

标准io

  • 除非引用终端设别,否则系统默认流打开是全缓冲的。
打开 
#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 参数指定操作类型,入读写,追加等等。

关闭
#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);
#上面三个函数的返回值为int,因为EOF常实现为-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由于没有指定缓冲区,所以有可能造成缓冲区溢出,要小心 

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

#格式化输出IO流
printf 输出到标准输出
fprintf 输出到指定流
sprintf 输出到指定数组
snprintf 输出到指定数组并在数组的尾端自动添加一个null字节

#格式化输入IO流
scanf 从标准输入获取
fscanf 从指定流获取
sscanf 从指定数组获取

网络高级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函数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容

  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 3,842评论 0 5
  • 第三章 文件i/o 3.1引言 不带缓冲的io(unix系统在内核中设有缓冲区,这个不带缓冲意思是用户不自己缓冲)...
    m风满楼阅读 995评论 0 0
  • 1,tableview点击选中效果,放开点击后选中效果消失。只需重写tableview的delegate方法 2,...
    keking阅读 535评论 0 0
  • 01 2017年高三毕业的那个夏天,从6月9号到9月1号,差不多三个月的时间,现在回忆起来是又遥远又模糊的昨天了。...
    炸鸡腿我都吃了阅读 435评论 4 6
  • 巴菲特的一生充满了传奇和秘密。 听说过巴菲特的人都知道他有几个标签,股神,世界首富,投资家。 但这些标签,都掩盖了...
    核聚阅读 1,374评论 0 1