首先,先稍微了解系统调用的概念:
       系统调用,英文名system call,每个操作系统都在内核里有一些内建的函数库,这些函数可以用来完成一些系统系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序,如果没有系统调用和内核函数,用户将不能编写大型应用程序,及别的功能,这些函数集合起来就叫做程序接口或应用编程接口(Application Programming Interface,API),我们要在这个系统上编写各种应用程序,就是通过这个API接口来调用系统内核里面的函数。如果没有系统调用,那么应用程序就失去内核的支持。
     现在,再聊不带缓存的I/O操作:
     linix对IO文件的操作分为不带缓存的IO操作和标准IO操作(即带缓存),刚开始,要明确以下几点:
     1:不带缓存,不是直接对磁盘文件进行读取操作,像read()和write()函数,它们都属于系统调用,只不过在用户层没有缓存,所以叫做无缓存IO,但对于内核来说,还是进行了缓存,只是用户层看不到罢了。如果这一点看不懂,请看第二点;
    2:带不带缓存是相对来说的,如果你要写入数据到文件上时(就是写入磁盘上),内核先将数据写入到内核中所设的缓冲储存器,假如这个缓冲储存器的长度是100个字节,你调用系统函:

ssize_t write (int fd,const void * buf,size_t count);

写操作时,设每次写入长度count=10个字节,那么你几要调用10次这个函数才能把这个缓冲区写满,此时数据还是在缓冲区,并没有写入到磁盘,缓冲区满时才进行实际上的IO操作,把数据写入到磁盘上,所以上面说的“不带缓存不是就没有缓存直写进磁盘”就是这个意思。

那么,既然不带缓存的操作实际在内核是有缓存器的,那带缓存的IO操作又是怎么回事呢?

带缓存IO也叫标准IO,符合ANSI C 的标准IO处理,不依赖系统内核,所以移植性强,我们使用标准IO操作很多时候是为了减少对read()和write()的系统调用次数,带缓存IO其实就是在用户层再建立一个缓存区,这个缓存区的分配和优化长度等细节都是标准IO库代你处理好了,不用去操心,还是用上面那个例子说明这个操作过程:

上面说要写数据到文件上,内核缓存(注意这个不是用户层缓存区)区长度是100字节,我们调用不带缓存的IO函数write()就要调用10次,这样系统效率低,现在我们在用户层建立另一个缓存区(用户层缓存区或者叫流缓存),假设流缓存的长度是50字节,我们用标准C库函数的fwrite()将数据写入到这个流缓存区里面,流缓存区满50字节后在进入内核缓存区,此时再调用系统函数write()将数据写入到文件(实质是磁盘)上,看到这里,你用该明白一点,标准IO操作fwrite()最后还是要掉用无缓存IO操作write,这里进行了两次调用fwrite()写100字节也就是进行两次系统调用write()。

如果看到这里还没有一点眉目的话,那就比较麻烦了,希望下面两条总结能够帮上忙:

无缓存IO操作数据流向路径:数据——内核缓存区——磁盘

标准IO操作数据流向路径:数据——流缓存区——内核缓存区——磁盘

这里为了说明标准I/O的工作原理,借用了glibc中标准I/O实现的细节,所以代码多是不可移植的.

这两天在看UNIX环境高级编程,再来点基础的(发现自己是越来越弱了

首先说说不带缓存的I/O,UNIX的文件I/O read、write是不带缓存的。不带缓存是指每个read、write都调用内核的一个系统调用,它们是POSIX.1的组成部分。二者的原型为:

ssize_t read( int filedes, void* buf, size_t nbytes );    // 若成功返回读到的字节数

ssize_t write( int filedes, const void* buf, size_t nbytes );    // 若成功返回已写的字节数

注意,上面的buf不是指read、write带缓存,而是当read时用来存放读出的字节,write时存放待写的字节。对于read,nbytes表示每次最多读的字节数。但这个块的大小将影响I/O的效率,其值和具体系统有关。

充一下,不带缓存的I/O对文件描述符操作,下面带缓存的I/O是针对流的。

标准I/O库就是带缓存的I/O,它由ANSI C标准说明。当然,标准I/O最终都会调用上面的I/O例程。标准I/O库代替用户处理很多细节,比如缓存分配、以优化长度执行I/O等。

标准I/O提供缓存的目的就是减少调用read和write的次数,它对每个I/O流自动进行缓存管理(标准I/O函数通常调用malloc来分配缓存)。它提供了三种类型的缓存:

1) 全缓存。当填满标准I/O缓存后才执行I/O操作。磁盘上的文件通常是全缓存的。

2) 行缓存。当输入输出遇到新行符或缓存满时,才由标准I/O库执行实际I/O操作。stdin、stdout通常是行缓存的。

3) 无缓存。相当于read、write了。stderr通常是无缓存的,因为它必须尽快输出。

一般而言,由系统选择缓存的长度,并自动分配。标准I/O库在关闭流的时候自动释放缓存。

在标准I / O库中,一个效率不高的不足之处是需要复制的数据量。当使用每次一行函数fgets和fputs时,通常需要复制两次数据:一次是在内核和标准I / O缓存之间(当调用read和write时),第二次是在标准I / O缓存(通常系统分配和管理)和用户程序中的行缓存(fgets的参数就需要一个用户行缓存指针)之间。

不管上面讲的到底懂没懂,记住一点:

使用标准I / O例程的一个优点是无需考虑缓存及最佳I / O长度的选择,并且它并不比直接调用read、write慢多少。

 
 
 
 

不带缓存的I/O和标准(带缓存的)I/O的更多相关文章

  1. nginx反向代理+缓存开启+url重写+负载均衡(带健康探测)的部署记录

    在日常运维工作中,运维人员会时常使用到nginx的反向代理,负载均衡以及缓存等功能来优化web服务性能. 废话不多说,下面对测试环境下的nginx反向代理+缓存开启+url重写+负载均衡(带健康探测) ...

  2. 浅谈无缓存I/O操作和标准I/O文件操作差别

    首先,先略微了解系统调用的概念:        系统调用,英文名system call,每一个操作系统都在内核里有一些内建的函数库,这些函数能够用来完毕一些系统系统调用把应用程序的请求传给内核,调用对 ...

  3. 无缓存I/O操作和标准I/O文件操作区别

    本文转载于:http://www.360doc.com/content/11/0521/11/5455634_118306098.shtml 首先,先稍微了解系统调用的概念:       系统调用,英 ...

  4. ASP.NET缓存全解析7:第三方分布式缓存解决方案 Memcached和Cacheman 转自网络原文作者李天平

    Memcached — 分布式缓存系统 1.Memcached是什么? Memcached是高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度.Memcached通过在内 ...

  5. ASP.NET缓存全解析3:页面局部缓存 转自网络原文作者李天平

    有时缓存整个页面是不现实的,因为页的某些部分可能在每次请求时都需要变化.在这些情况下,只能缓存页的一部分.顾名思义,页面部分缓存是将页面部分内容保存在内存中以便响应用户请求,而页面其他部分内容则为动态 ...

  6. 缓存(之一) 使用Apache Httpd实现http缓存

    http://www.tuicool.com/articles/EFfeu2 HTTP性能的问题与方案 一个最终用户访问一个网页,从浏览器发出请求,到接受请求,时间大体上消耗在了以下几个部分: 建立t ...

  7. WEB 应用缓存解析以及使用 Redis 实现分布式缓存

    什么是缓存? 缓存就是数据交换的缓冲区,用于临时存储数据(使用频繁的数据).当用户请求数据时,首先在缓存中寻找,如果找到了则直接返回.如果找不到,则去数据库中查找.缓存的本质就是用空间换时间,牺牲数据 ...

  8. SpringBoot缓存管理(三) 自定义Redis缓存序列化机制

    前言 在上一篇文章中,我们完成了SpringBoot整合Redis进行数据缓存管理的工作,但缓存管理的实体类数据使用的是JDK序列化方式(如下图所示),不便于使用可视化管理工具进行查看和管理. 接下来 ...

  9. ThinkPHP中的动态缓存(S方法)和快速缓存(F方法)

    系统默认的缓存方式是采用File方式缓存,我们可以在项目配置文件里面定义其他的缓存方式,例如,修改默认的缓存方式为Xcache(当然,你的环境需要支持Xcache)    对于File方式缓存下的缓存 ...

随机推荐

  1. 在FreeBSD上搭建Mac的文件及time machine备份服务

    上周将工作用电脑由公司配备的台式机切换到自己低配的macbook air上面,小本本的128G SSD远远不能满足工作的储存需要,但又不舍得入手昂贵的AirPort Time Capsule,于是考虑 ...

  2. Java 调用 Javascript 函数的范例

    在Java 7 以后,可以在Java代码中调用javascript中的函数,请看下面的例子: package com.lee; import java.io.FileNotFoundException ...

  3. git manual

    git init                                                  # 初始化本地git仓库(创建新仓库) git config --global us ...

  4. ptype_base和ptype_all学习笔记

    "linux-2.6.32/include/linux/netdevice.h" struct packet_type { __be16 type; /* This is real ...

  5. mysql 重置root 账户密码

    windows: 打开命令行窗口,停止mysql服务:        Net stop mysql启动mysql,一般到mysql的安装路径,找到 mysqld-nt.exe <<< ...

  6. bzoj 3293 数学整理

    和1045一模一样,找到这道题的时候还愣了下神,最后发现样例都是 一样的,直接粘了1045的代码,具体题解看 http://www.cnblogs.com/BLADEVIL/p/3468729.htm ...

  7. nginx+php+flight 构建RESTFul API

    配置: Nginx: conf目录下nginx.conf配置文件. 第44行改为:root   D:/wwwroot/www; 第45行改为:index  index.html index.htm i ...

  8. 5-Highcharts曲线图之轴反转

    <!DOCTYPE> <html lang='en'> <head> <title>5-Highcharts曲线图之轴反转</title> ...

  9. Auto Layout - 使用总结

    1.要开始使用AutoLayout,请先设置要约束的view的translatesAutoresizingMaskIntoConstraints属性为NO.在xib或者sb中勾选Use Auto La ...

  10. 引擎设计跟踪(九.9) 文件包系统(Game Package System)

    很早之前,闪现过写文件包系统的想法, 但是觉得还没有到时候. 由于目前工作上在做android ndk开发, 所以业余时间趁热做了android的移植, 因为android ndk提供的mountab ...