<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>
作者:华清远见高级讲师 曾宏安老师
学习过编程的朋友都知道ANSI C里定义的标准I/O是一种带缓冲的高级磁盘I/O,目的是尽可能减少使用read和write系统调用的次数,从而提高I/O效率。标准I/O提供了3种类型的缓冲类型。
Ø 全缓冲。在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。对驻留在磁盘上的文件的访问通常是由标准I/O库实施全缓冲的。
Ø 行缓冲。在这种情况下,当在输入和输出中遇到新行符时,标准I/O库执行I/O操作,这允许我们一次输出一个字符(如fputc函数),但只有写了一行之后才进行实际I/O操作。当流涉及一个终端时(例如标准输入和标准输出),典型地使用行缓冲。
Ø 不带缓冲。标准I/O库不对字符进行缓冲。如果用标准I/O函数写若干字符到不带缓冲的流中,则相当于用write系统调用将这些字符写到打开的文件上。标准出错况stderr通常是不带缓存的,这就使得出错信息可以尽快显示出来。
这里强调一下,所谓的带不带缓冲指的是不同的流而不是函数。比如驻留在磁盘上的文件流是全缓冲的方式,标准输入/输出流缺省是行缓冲而标准错误不带缓冲。
行缓冲是指当遇到换行符’\n’或一行满时,才真正的进行I/O操作。Linux缺省情况下一行最多容纳1024个字符,当超出这个范围时,即使没有遇到换行符,也引起实际的I/O操作。
对于全缓冲来说,读写操作是按照缺省的缓冲区大小(4K)进行的。具体说就是从流读取内容时每次读取4K大小的内容到缓冲区,而程序是从缓冲区里读取数据的。当缓冲区里的数据处理完后再从流里读取4K的内容到缓冲区。分析下面的例子:
FILE *fp;
char buf[8192] = {0}; // 缓冲区初始化为0
char ch;
if ( (fp=fopen (“data.txt”, “r+”)) == NULL )
{
printf(“Fail to open file\n”);
exit(-1);
}
setvbuf(fp, buf, _IOFBF, 4096); // 设置流fp为全缓冲,缓冲区指向buf,大小为4096
fread(&ch, 1, 1, fp); // 从流中读取一个字节的内容存放到变量ch中
printf(“%d %d %d\n”, buf[0], buf[1], buf[4095]); 虽然程序中只读取了1个字节,但实际上读取了4K的内容存放到buf中。
写文件的情况类似,当缓冲区写满内容时才会引起实际的I/O操作,文件被更新。
又读又写的情况比较特殊。因为读写缓冲区只有一个,所以在读取内容到缓冲区之前会先把缓冲区里要更新的内容(如果有的话)写到文件。还有一种情况也会引起实际写操作,那就是fseek函数的调用。
分享到:
相关推荐
在电子设计自动化(EDA)和可编程逻辑器件(PLD)的领域中,理解标准I/O缓冲区的概念至关重要,因为它关系到程序的性能和效率。标准I/O缓冲区是ANSI C标准的一部分,用于优化磁盘I/O操作,减少对操作系统内核的系统...
《浅析Linux环境下文件I/O操作》这篇文章主要探讨了Linux操作系统中进行文件输入/输出(I/O)操作的相关概念和技术。在Linux系统中,一切皆为文件,包括硬件设备,因此,程序对文件和设备的操作具有统一的接口。系统...
- 完成复制后,内核将控制权交还给用户线程,此时用户线程可以从缓冲区读取数据并继续执行后续任务。 **伪代码示例**: ```c read(socket, buffer); // 线程在此处被阻塞 process(buffer); // 处理接收到的数据 ```...
- **ChannelBufferFactory**:创建和管理ChannelBuffer的工厂,可以定制不同的缓冲区实现,以满足不同性能需求。 3. **ChannelPipeline**: - ChannelPipeline是Netty中处理I/O事件的通道,它包含一系列...
Oracle数据库性能优化是一个系统性的工程,涉及到数据库的多个核心组件,包括系统全局区域(SGA)、共享池、数据缓冲区高速缓存、重做日志缓冲区、PGA(程序全局区域)以及磁盘I/O等多个方面。下面将根据提供的文件...
Netty使用`ChannelBuffer`接口来封装缓冲区的功能,提供了比标准Java NIO `ByteBuffer`更高级的操作方式。 1. **HeapChannelBuffer**:这是Netty提供的一个实现`ChannelBuffer`接口的具体类。它的数据存储在Java堆...
1. **HeapChannelBuffer**:这是一种基于堆内存的实现方式,即缓冲区位于Java虚拟机的堆内存中。它适用于大多数情况下的数据传输需求。 2. **DirectChannelBuffer**:这是一种基于直接内存的实现方式,即缓冲区位于...
- I/O线程:处理数据的读写操作,可能涉及磁盘I/O和网络I/O。 - 会话线程:维护与客户端的连接,接收请求,将请求放入任务队列等待执行。 - 监听线程:负责监听新的客户端连接请求。 - 日志线程:处理日志记录,...
- 读取数据:为了从UART接收数据,驱动程序需要包含一个函数,循环检查UART的接收缓冲区,当有新的字符到来时,将数据从硬件接收寄存器读取并存储到内存中。 - 写入数据:同样,驱动程序需要提供一个函数用于向...
同时,Netty 提供了多种ChannelBufferFactory,可以根据需求选择合适的缓冲区类型。 总的来说,Netty 的实现原理涵盖了网络I/O模型、事件驱动机制、线程池管理以及高效的数据缓冲技术。这些设计使得Netty成为了Java...
- **系统缓冲区管理**:缓存常用数据,减少磁盘I/O,提升性能。 - **并发控制/封锁子系统**:保证多用户并发访问数据时的一致性和完整性。 - **事务管理**:管理数据库事务的提交、回滚和并发操作。 - **日志...
7. IBIS模型的应用:IBIS模型是一种行为级模型,它提供I/O缓冲区的电气特性,例如驱动器和接收器的电压和电流关系,用于在不泄露具体电路设计细节的情况下进行仿真,这对于高速PCB设计中的信号完整性分析非常有用。...
总结,Java NIO是一个强大的工具,它改变了Java处理I/O的方式,提升了并发性能。理解和掌握NIO,对于任何Java开发者来说,都能在开发高性能应用时游刃有余。在实际开发中,结合具体需求,灵活运用NIO,可以极大地...
在Windows 2000下,虚拟硬盘的实现涉及到驱动程序的编写,需要对Windows驱动模型有深入理解,包括IRP(I/O请求包)处理、缓冲区管理和设备管理等。 “Windows虚拟磁盘与路径容错”是一个关键的话题,它涉及到如何...
在Linux系统中,I/O多路复用技术如epoll是一种高效的进程间通信方式,用于管理多个文件描述符(FD)的状态。本文将深入解析epoll的两种触发模式:水平触发(Level Triggered, LT)和边缘触发(Edge Triggered, ET)...
1. **消除不必要的大表全表扫描**:全表扫描会导致大量的I/O操作,严重影响数据库性能。可以通过增加索引来减少不必要的全表扫描。 - 在有序表中,如果查询返回的行数少于40%; - 在无序表中,如果查询返回的行数...
这个过程涉及四次数据拷贝,包括磁盘到内核缓冲区、内核缓冲区到用户缓冲区、用户缓冲区到内核socket缓冲区以及内核socket缓冲区到网络。此外,频繁的上下文切换也会增加CPU的负担。 为了解决这个问题,Linux提供了...
它的运行机制涉及到I/O流(Input/Output Stream)的概念,特别是缓冲区(Buffer)和流操作的顺序。下面我们将深入探讨`cout`的工作原理以及上述代码示例所体现的输出规则。 I/O流在C++中是以缓冲区为基础的,这意味...