流与缓冲区

我是 C 的新手。我目前正在阅读 K&R。在那里我对文本流的定义感到困惑“文本流是分成新行的字符序列;每行由 0 个或多个字符组成,后跟一个换行符。” 为了了解这个流,我被引入了一个新术语,即缓冲区。

我只知道:

  • 输入和输出设备之间的连续数据流(字节或字符)是
  • 主存中的一个临时存储区,用于临时存储输入或输出数据 是一个BUFFER

我不是说我是对的,但这是我对这些条款的基本想法。

我想知道,在 C 实现的非抽象级别中,缓冲区和流究竟是什么,以及这两个事物(即流和缓冲区)如何协同工作。

likewindyaya 回答:流与缓冲区

您在 C 中有 stdinstdoutstderr 三个流,您还可以将使用 fopen 打开的文件视为一个流。 stdin 通常是键盘,stdout 通常是您的显示器,stderr 通常也是您的显示器。但它们不一定是,它们是硬件的抽象。

例如,如果您在银行 ATM 上没有键盘但有键盘,那么 stdin 将是键盘,如果您没有显示器而是有打印机,则 { {1}} 将是打印机。您可以通过调用操作系统来更改他们使用的硬件。您还可以再次通过调用您的操作系统来改变他们的行为,这超出了您的要求。

因此,在某种程度上,可以将缓冲区视为由与流关联的操作系统分配的内存,用于保存从硬件组件接收到的数据。例如,当您在键盘上键入时,您键入的字符不会被 IDE 直接捕获,它们会从那里移动到缓冲区中,然后您读取缓冲区。

这就是为什么,例如,您必须在代码开始与键盘输入的任何内容交互之前按 Enter 键,因为 stdout 是行缓冲的。控制权从您的程序传递到操作系统,直到它遇到将控制权发回给您的程序的东西,在正常情况下,这将是换行符。

所以从某种意义上说,流是设备(键盘、显示器或硬盘上的文件),缓冲区是操作系统控制时保存数据的地方,然后您在处理数据时与缓冲区进行交互。

该抽象允许您以通用方式使用所有这些不同的东西,而不管它们是什么,例如:stdin ...流可以是任何输入流,无论是 fgets(str,sizeof(str),STREAM) 还是一个文件。

更进一步,这就是为什么新程序员会因为 stdin 后跟 scanf 而被 int 抛弃,因为 fgets 读取 scanf从缓冲区中但将 int 留在缓冲区中......然后对 \n 的调用读取 fgets 留在那里的 \n 并且新程序员不知道为什么他们无法输入任何数据。因此,您对流和缓冲区的好奇心将有助于您继续学习 C。

,

定义还不错,实际上非常好。您可以添加(从面向对象的角度),STREAM 使用 BUFFER。

可能需要使用 BUFFER,例如性能原因,因为每个系统调用都会带来相对较高的成本。

与内存访问时间相比,尤其是 IO 系统调用、硬盘或网络访问速度较慢。如果读取或写入仅包含一个字节,它们就会相加。

,

I/O 设备的两种常见抽象是:

Streams - 在设备准备就绪时传输可变数量的字节。

块 - 传输固定大小的记录。

缓冲区只是一块存储正在传输的数据的内存区域。

,

这些实际上是很好的工作定义。

在实际的 C 术语中,buffer 是一个数组(通常是 charunsigned char 类型),用于存储数据,或者作为输入操作的结果,或在发送到输出之前。数组可以声明为固定大小的数组,如

char buffer[SOME_BUFFER_SIZE];

或动态地,使用

char *buffer = malloc( SOME_BUFFER_SIZE * sizeof *buffer );

使用动态内存的好处是可以根据需要调整缓冲区大小;缺点是您必须管理该内存的生命周期。

对于文本输入/输出,您通常会使用 char 数组;对于二进制输入/输出,您通常会使用 unsigned char 数组。

通过网络进行通信的系统以固定大小的“块”发送数据是相当常见的,因此您可能需要多次读取或写入操作来获取所有数据。考虑一个 Web 服务器和一个浏览器 - 服务器在多条消息中发送 HTML,浏览器将中间结果存储在缓冲区中。只有当浏览器接收到所有数据时,才会呈现页面:

Received from Web server       Stored in browser's input buffer
------------------------       --------------------------------
HTTP/1.1 200 OK \r\n           <!DOCTYPE HTML><html
Content-length: 20\r\n
<!DOCTYPE HTML><html

HTTP/1.1 200 OK \r\n           <!DOCTYPE HTML><html><head><title>This i
Content-length: 20\r\n
><head><title>This i

HTTP/1.1 200 OK \r\n           <!DOCTYPE HTML><html><head><title>This i
Content-length: 20\r\n         s a test</title></he
s a test</title></he

HTTP/1.1 200 OK \r\n           <!DOCTYPE HTML><html><head><title>This i
Content-length: 20\r\n         s a test</title></head><body><p>Hello,W
ad><body><p>Hello,W

HTTP/1.1 200 OK \r\n           <!DOCTYPE HTML><html><head><title>This i
Content-length: 19             s a test</title></head><body><p>Hello,W
orld!</body></html>            orld!</body></html>

没有健全的服务器以 20 个字符的块发送 HTML,但这应该说明为什么以及如何使用缓冲区。

本文链接:https://www.f2er.com/9727.html

大家都在问