1.5 输入和输出

不带缓冲的I/O: 首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用。系统内核对磁盘的读写都会提供一个块缓冲(在有些地方也被称为内核高速缓存),当用write函数对其写数据时,直接调用系统调用,将数据写入到块缓冲进行排队,当块缓冲达到一定的量时,才会把数据写入磁盘。因此所谓的不带缓冲的I/O是指进程不提供缓冲功能(但内核还是提供缓冲的)。每调用一次write或read函数,直接系统调用。
带缓冲的I/O是指进程对输入输出流进行了改进,提供了一个流缓冲,当用fwrite函数网磁盘写数据时,先把数据写入流缓冲区中,当达到一定条件,比如流缓冲区满了,或刷新流缓冲,这时候才会把数据一次送往内核提供的块缓冲,再经块缓冲写入磁盘。(双重缓冲)

因此,带缓冲的I/O在往磁盘写入相同的数据量时,会比不带缓冲的I/O调用系统调用的次数要少。

linux read()函数:read函数从打开的设备或文件中读取数据。

#include <unistd.h>    
ssize_t read(int fd, void *buf, size_t count);  
返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0
参数
count
是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移。
 

#include "apue.h"
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFFSIZE 3
int main(void)
{
   int n;
   n=0;
   printf("n = %d",n);
   int c=open("./kc.txt",O_RDONLY);
   char buf[BUFFSIZE];
   while((n=read(c,buf,BUFFSIZE))>0)
        {
           printf("n = %d  ",n);
           if(write(STDOUT_FILENO,buf,n)!=n)
                   err_sys("write error");
        }
           if(n<0)
             err_sys("read error");
   //exit(0);
  return 0;
}

问题:read函数在读的文件的字节数小于buffsize时候为啥不出错,文件只有两个字节返回的为何是3个字节。为何read中有标准输入的时候,printf函数就无效了。

STDIN_FILENO与STDOUT_FILENO阻塞了printf,要这两个关闭之后才会显示printf的内容。

read函数会去读取BUFFERSIZE数量的文件内容,直到遇到文件结尾‘\0',会将该文件结尾读入。然后下次再读的时候就返回0。

ynnnnd
*** stack smashing detected ***: ./test terminated
n = 3  n = 3  n = 1  Aborted (core dumped)

如果buf的大小小于buffersize也会正常读写,只不过会碰到一个问题,最后会抛出段错误的信息,也就是栈溢出
POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ),POSIX标准定义了操作系统应该为应用程序提供的接口标准,是IEEE为要在各种UNIX操作系统上运行的软件而定义的一系列API标准的总称,其正式称呼为IEEE 1003,而国际标准名称为ISO/IEC 9945。

Ctrl+D文件结束符


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值