一、什么是缓存I/O(Buffered I/O)
缓存I/O又被称作标准I/O,大多数文件系统默认I/O操作都是缓存I/O。在Linux的缓存I/O机制中,操作系统会将I/O的数据缓存在文件系统的页缓存(page cache)中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。
1.缓存I/O有以下优点:
A.缓存I/O使用了操作系统内核缓冲区,在一定程度上分离了应用程序空间和实际的物理设备。
B.缓存I/O可以减少读盘的次数,从而提高性能
当应用程序尝试读取某块数据的时候,如果这块数据已经存放在页缓存中,那么这块数据就可以立即返回给应用程序,而不需要经过实际的物理读盘操作。当然,如果数据在应用程序读取之前并未被存放在页缓存中,那么就需要先将数据从磁盘读到页缓存中去。对于写操作来说,应用程序也会将数据先写到页缓存中去,数据是否被立即写到磁盘上去取决于应用程序所采用的写操作机制:如果用户采用的是同步写机制,那么数据会立即被写回到磁盘上,应用程序会一直等到数据被写完为止;如果用户采用的是延迟写机制,那么应用程序就完全不需要等到数据全部被 写回到磁盘,数据只要被写到页缓存中去就可以了。在延迟写机制的情况下,操作系统会定期地将放在页缓存中的数据刷到磁盘上。与异步写机制不同的是,延迟写机制在数据完全写到磁盘上得时候不会通知应用程序,而异步写机制在数据完全写到磁盘上得时候是会返回给应用程序的。所以延迟写机制本省是存在数据丢失的风险的,而异步写机制则不会有这方面的担心。
2.缓存I/O的缺点
在缓存I/O机制中,DMA方式可以将数据直接从磁盘读到页缓存中,或者将数据从页缓存直接写回到磁盘上,而不能直接在应用程序地址空间和磁盘之间进行数据传输,这样的话,数据在传输过程中需要在应用程序地址空间和页缓存之间进行多次数据拷贝操作,这些数据拷贝操作说带来的cpu以及内存开销是非常大的。
二、文件指针
FILE指针:每个被使用的文件都在内存中开辟一个区域,用来存放文件的有关信息,这些信息是保存在一个结构体类型的变量中,该结构体类型是由系统定义的,取名为FILE。
标准I/O库的所有操作都是围绕流(stream)来进行的,在标准I/O中,流用FILE *来描叙的。
其在Linux操作系统中的定义:
三、行缓冲、全缓冲、不缓冲的定义
1.Fully buffered means that I/O takes place only when the buffer is fully, the process explicitly calls fflush, or the process terminates by calling exit. A common size for the standard I/O buffer is 4096 bytes;
2. Line buffered means that I/O takes place when a newline is encountered, when the process calls fflush, or when the process terminates by calling exit.
3. Unbuffered means that I/O take place each time a standard I/O output function is called.
Most unix implementations of the standard I/O libarary use the following rules.
1. Standard error is always unbuffered.
2. Standard input and standard output are fully buffered, unless they refer to a terminal device, in which case, they are line buffered.
3. All other streams are fully buffered unless they refer to a terminal device,
in which case, they are line buffered.
四、一步步探究
#include <stdio.h>
int stream_attribute(FILE *fp)
{
if(fp->_flags & _IO_UNBUFFERED)
{
printf("The IO type is unbuffered\n");
}else if(fp->_flags & _IO_LINE_BUF){
printf("The IO type is line buf\n");
}else{
printf("The IO type is full buf\n");
}
printf("The IO size : %d\n",fp->_IO_buf_end - fp->_IO_buf_base);
return 0;
}
int main()
{
FILE *fp;
stream_attribute(stdin);
printf("___________________________________\n\n");
stream_attribute(stdout);
printf("___________________________________\n\n");
stream_attribute(stderr);
printf("___________________________________\n\n");
if((fp = fopen("test.txt","w+")) == NULL)
{
perror("fail to fopen");
}
stream_attribute(fp);
return 0;
}
运行结果:
我们修改一下代码再看
#include <stdio.h>
int stream_attribute(FILE *fp)
{
if(fp->_flags & _IO_UNBUFFERED)
{
printf("The IO type is unbuffered\n");
}else if(fp->_flags & _IO_LINE_BUF){
printf("The IO type is line buf\n");
}else{
printf("The IO type is full buf\n");
}
printf("The IO size : %d\n",fp->_IO_buf_end - fp->_IO_buf_base);
return 0;
}
int main()
{
FILE *fp;
getchar();
stream_attribute(stdin);
printf("___________________________________\n\n");
stream_attribute(stdout);
printf("___________________________________\n\n");
stream_attribute(stderr);
printf("___________________________________\n\n");
if((fp = fopen("test.txt","w+")) == NULL)
{
perror("fail to fopen");
}
printf("before write:\n");
stream_attribute(fp);
fputc('a',fp);
printf("after write:\n");
stream_attribute(fp);
return 0;
}
运行结果:
从以上我们可以看出,标准I/O并不是一开始就分配的,只有进行了输入或者输出的操作才进行分配的,标准输入和标准输出默认是全缓冲,但是如果和终端关了就是行缓冲。可以看到在linux操作系统中行缓冲的大小是1k,全缓冲的大小是4k。
- 浏览: 36784 次
相关推荐
1. **缓冲机制**:标准IO有自己的缓冲区,而文件IO通常没有,除非手动开启缓冲。 2. **性能**:标准IO因为有缓冲,可能在大量数据传输时表现更好;而文件IO通常更快,尤其是小块数据的读写。 3. **灵活性**:文件IO...
Linux中的标准IO具有缓冲机制,这是为了提高IO操作的性能。根据不同的应用场景,标准IO提供了三种类型的缓冲: 1. **全缓冲(Full Buffering)**:默认情况下,大多数标准IO流采用全缓冲模式。在这种模式下,只有当...
- 调用 `fwrite` 后,数据从 Application Buffer 复制到 C 库标准 IO 缓冲区 (CLib Buffer)。 - 当 `fclose` 被调用时,数据才会被刷新到磁盘上。此外,可以使用 `fflush` 将数据从 CLib Buffer 写入 Page Cache,但...
系统 IO 和标准 IO 的连续与区别 ...系统 IO 提供了基本的 IO 服务,而标准 IO 在文件 IO 的基础上封装了缓冲机制,提供了更高级的 IO 服务。在选择文件 IO 模式时,需要根据实际情况选择合适的模式。
标准I/O函数库将一些系统调用封装起来,提供了缓冲机制,减少了系统调用的次数,提高了程序运行效率。然而,标准I/O函数库并不适用于所有场合,因为它的封装层可能会引入额外的性能开销。在对性能要求极高的场景下,...
2. **标准 IO 操作**:基于 C 标准库提供的封装,提供了缓冲机制,从而提高了性能。标准 IO 的典型示例包括 `fopen`, `fclose`, `fread`, `fwrite` 等函数。 #### 文件描述符 在 Linux 中,每一个打开的文件都与一...
本讲座主要围绕"Linux文件IO编程"展开,由知名的教育机构华清远见出品,质量可靠,内容深入浅出。 首先,我们来了解一下Linux文件系统的基本概念。在Linux中,一切皆为文件,包括硬件设备、网络接口等,都被抽象为...
Linux 缓冲机制是操作系统中一个重要的组成部分,它在提高系统效率、优化资源利用方面起着关键作用。本文将深入探讨Linux缓冲机制的基本概念、作用以及分类。 首先,缓冲区,也称为缓存,是在内存中预留的一块特定...
了解这些层次及其工作原理对于深入理解Linux系统的IO机制至关重要。 1. **用户空间层**:应用程序通过标准的系统调用接口(如`read()`、`write()`等)来请求IO操作。 2. **文件系统层**:负责管理文件和目录的存储...
为了更好地管理和优化IO操作,Linux内核设计了一套复杂的IO数据通道处理机制。这一机制主要由几个关键层次构成: 1. **用户空间与内核空间交互层**:用户空间的应用程序通过系统调用如`read()`、`write()`等与内核...
本文将深入探讨Linux I/O的基础知识,包括I/O模型、缓冲机制以及相关的编程实践。 一、I/O模型 1. 同步I/O与异步I/O: - **同步I/O**:在数据传输期间,进程被阻塞,直到操作完成。例如,read()函数调用会阻塞,...
Linux中的标准I/O库(stdio.h)提供了缓冲I/O,数据在用户空间和内核空间之间有一个缓冲区,减少了系统调用的次数。直接I/O绕过了用户空间的缓冲,直接在内核空间和硬件之间传输数据,适用于高性能的I/O操作。 7. ...
### Linux异步IO aio #### 引言 随着网络技术的发展和CPU性能的提升,传统的网络编程接口(如Unix套接字API)已逐渐无法满足高效处理大量数据的需求。当前的操作系统在网络接口方面存在局限性,尤其是在数据传输...
### Linux直接I/O机制介绍 #### 直接I/O的动机与背景 在深入了解Linux中的直接I/O机制之前,我们首先需要理解为什么需要这样的机制。传统操作系统中的I/O操作通常是通过缓存I/O来完成的,即数据在传输过程中会先...
无缓存I/O操作与标准I/O文件操作之间的主要区别在于数据处理的层次和缓存机制。系统调用是操作系统内核提供给应用程序的一种接口,允许应用程序请求内核执行特定的任务,如I/O操作。在I/O操作中,无论是无缓存还是...
在这种机制中,操作系统维护了一个页缓存(page cache),数据首先被拷贝到内核的缓冲区,然后再拷贝到应用程序的地址空间。这种方法有其优点: 1. 分离了应用程序和物理设备,提高了系统的灵活性。 2. 减少了对...
#### 缓冲机制 - **缓冲文件系统**: - **全缓存**:当缓存填满后才会执行实际的I/O操作。 - **行缓存**:在输入输出过程中遇到`\n`时触发I/O操作,适用于终端输入输出。 - **不带缓存**:对于需要立即响应的操作...
这些实训有助于加深对Linux文件系统和文件操作机制的理解,并能在嵌入式系统中有效地应用文件IO接口进行数据的存储和管理。实训项目可能还会涵盖错误处理和异常情况的处理,确保文件操作的稳定性和可靠性。此外,...
本资料包主要探讨了Direct I/O在Linux中的使用,包括非缓冲读写、初级I/O和标准I/O的对比以及raw I/O的相关内容。 首先,让我们来理解Linux中的标准I/O和非缓冲读写。标准I/O,也就是我们通常所说的缓冲I/O,是操作...