【玩转Linux】标准io缓冲区的操作

这篇具有很好参考价值的文章主要介绍了【玩转Linux】标准io缓冲区的操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • (꒪ꇴ꒪ ),hello我是祐言
  • 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
  • 快上🚘,一起学习!
  • 送给读者的一句鸡汤🤔:
  • 集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏

一、缓冲区概念

        标准I/O缓冲区是用于提高I/O性能的一种机制,它位于标准C库中,并由标准I/O函数自动管理。标准I/O库通过在内存中创建缓冲区来减少频繁的系统调用,从而提高读写操作的效率。

标准I/O库使用三种类型的缓冲区:

【玩转Linux】标准io缓冲区的操作,玩转Linux,linux,php,服务器

        1. 全缓冲(Fully Buffered)

         当使用全缓冲模式时,标准I/O库会在内存中创建一个较大的缓冲区(通常大小为BUFSIZ),直到缓冲区被填满或遇到换行符('\n')时才会将数据写入磁盘。全缓冲适用于文件和大量数据的I/O操作,减少了系统调用的次数,提高了效率。

        2. 行缓冲(Line Buffered

         行缓冲模式下,标准I/O库会在遇到换行符('\n')时将数据写入磁盘,或者当缓冲区被填满时也会进行写入。行缓冲适用于终端设备(如终端窗口),可以保证每行数据都及时输出,方便用户查看输出结果。

        3. 无缓冲(Unbuffered)

         无缓冲模式下,标准I/O库会立即将数据写入磁盘,不使用缓冲区。每次调用I/O函数都会导致实际的系统调用,适用于需要立即刷新数据到磁盘的场景,如实时输出错误信息。

        标准I/O函数会自动选择合适的缓冲模式,但你也可以使用setvbuf函数来显式地设置缓冲模式和自定义缓冲区。

        对于标准输入(stdin)、标准输出(stdout)和标准错误(stderr),它们的默认缓冲模式通常是行缓冲(对于交互式终端)或全缓冲(对于文件和重定向)。

        需要注意的是,标准I/O缓冲区是由C库管理的,所以在使用标准I/O函数时,要确保及时刷新缓冲区,以免数据在缓冲区中滞留而未及时输出。可以使用fflush函数来手动刷新缓冲区,确保数据及时写入磁盘或终端。

二、SETBUF函数

  setbuf函数用于设置标准I/O流的缓冲区,从而控制I/O的缓冲方式。它允许你自定义缓冲区,或者禁用缓冲。setbuf函数的原型如下:

#include <stdio.h>
​
void setbuf(FILE *stream, char *buffer);

        参数说明:

  • stream:指向要设置缓冲区的文件流,可以是标准输入(stdin)、标准输出(stdout)、标准错误(stderr)或者其他已打开的文件流。

  • buffer:指向自定义缓冲区的指针。如果传递NULL,则表示禁用缓冲,使I/O变为无缓冲。

setbuf函数允许两种方式的缓冲:

  1. 全缓冲:如果buffer指向一个大小大于0的缓冲区,那么I/O操作将使用全缓冲模式。这意味着在填满整个缓冲区或者遇到换行符('\n')时,才会进行实际的I/O操作。

  2. 无缓冲:如果buffer为NULL,或者大小为0,那么I/O操作将变为无缓冲模式。这意味着每次调用输出函数(printfputchar等)或者输入函数(scanfgetchar等),都会立即进行I/O操作,而不会在内存中缓冲数据。

在使用setbuf函数时,要注意以下几点:

  1. 调用setbuf函数应该在打开文件流或者任何I/O操作之前,否则可能不会生效。

  2. 如果要使用自定义的缓冲区,确保缓冲区足够大,以避免缓冲区溢出。

  3. 如果设置为无缓冲,要注意频繁的I/O操作可能会导致性能下降,因为每次调用I/O函数都会进行实际的I/O操作,这会增加系统开销。

  4. 当使用自定义缓冲区时,不要在buffer指向的缓冲区被释放或者失效后再进行I/O操作,以免导致未定义的行为。

        示例:使用全缓冲模式设置标准输出(stdout)的缓冲区为一个大小为BUFSIZ(通常是1024字节)的缓冲区。

#include <stdio.h>
​
int main() {
    char buf[BUFSIZ];
    setbuf(stdout, buf);
​
    printf("This will be buffered\n");
    fflush(stdout); // 强制刷新缓冲区,立即输出
    printf("This will also be buffered\n");
​
    return 0;
}

        示例:禁用标准输出(stdout)的缓冲区,使其变为无缓冲模式。

#include <stdio.h>
​
int main() {
    setbuf(stdout, NULL); // 禁用缓冲
​
    printf("This will be immediately output\n");
    printf("No buffering in this case\n");
​
    return 0;
}

三、SETVBUF函数

   setvbuf函数也是用于设置标准I/O流的缓冲方式,与setbuf函数类似,但提供更灵活的缓冲控制。setvbuf函数允许你自定义缓冲区,并且可以指定缓冲类型,包括全缓冲、行缓冲和无缓冲。它的原型如下:

#include <stdio.h>
​
int setvbuf(FILE *stream, char *buffer, int mode, size_t size);

参数说明:

  • stream:指向要设置缓冲区的文件流,可以是标准输入(stdin)、标准输出(stdout)、标准错误(stderr)或者其他已打开的文件流。

  • buffer:指向自定义缓冲区的指针。如果传递NULL,则会使用系统默认的缓冲区。

  • mode:指定缓冲类型,可以是以下值之一:

    • _IOFBF:全缓冲模式。使用指定的缓冲区,并在填满整个缓冲区时才进行实际的I/O操作。

    • _IOLBF:行缓冲模式。使用指定的缓冲区,并在遇到换行符('\n')时才进行实际的I/O操作。

    • _IONBF:无缓冲模式。禁用缓冲,每次调用I/O函数都会立即进行实际的I/O操作。

  • size:指定缓冲区大小。对于全缓冲和行缓冲模式,size表示缓冲区大小;对于无缓冲模式,size被忽略,可以设置为0。

   setvbuf函数的返回值是非零值表示成功,返回0表示失败。

        另外在使用setvbuf函数时,可以根据需要设置不同类型的缓冲模式和缓冲区大小。对于全缓冲和行缓冲,需要确保缓冲区足够大,以避免缓冲区溢出。而对于无缓冲模式,要注意频繁的I/O操作可能会导致性能下降。

        示例:使用全缓冲模式设置标准输出(stdout)的缓冲区为一个大小为BUFSIZ(通常是1024字节)的缓冲区。

#include <stdio.h>
​
int main() {
    char buf[BUFSIZ];
    setvbuf(stdout, buf, _IOFBF, BUFSIZ);
​
    printf("This will be buffered\n");
    fflush(stdout); // 强制刷新缓冲区,立即输出
    printf("This will also be buffered\n");
​
    return 0;
}

        示例:使用行缓冲模式设置标准输出(stdout)的缓冲区。

#include <stdio.h>
​
int main() {
    char buf[BUFSIZ];
    setvbuf(stdout, buf, _IOLBF, BUFSIZ);
​
    printf("This will be line buffered\n");
    printf("This will also be line buffered\n");
​
    return 0;
}

        示例:禁用标准输出(stdout)的缓冲区,使其变为无缓冲模式。

#include <stdio.h>
​
int main() {
    setvbuf(stdout, NULL, _IONBF, 0); // 禁用缓冲
​
    printf("This will be immediately output\n");
    printf("No buffering in this case\n");
​
    return 0;
}

        但要注意:在某些系统上,对标准输入(stdin)和标准输出(stdout)的缓冲设置可能不会生效,因为它们是由标准库提供的,并且可能使用了系统默认的缓冲设置。所以在实际使用中,最好将setvbuf函数用于文件流而不是标准输入和标准输出。

        更多C语言Linux系统相关文章,关注专栏:

   手撕C语言

            玩转linux文章来源地址https://www.toymoban.com/news/detail-604816.html

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉感谢关注🎉

到了这里,关于【玩转Linux】标准io缓冲区的操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux操作系统——重定向与缓冲区

    上一篇文章(文件详解)我们一直在谈,一个文件要被访问就必须要先被打开,打开之前就必须要先把文件加载到内存,同时呢我们的操作系统为了管理文件也会为我们的文件创建相对应的struct file对象,那么这个struct file对象里面应该有什么? 其实struct file里面最核心的两个

    2024年01月16日
    浏览(37)
  • 【C语言趣味教程】(8) 标准 IO 流:输入和输出 | 标准输入 stdin | 标准输出 stdout | 详解 printf 和 scanf | 探讨 scanf 缓冲区问题和安全性问题

        🔗 《C语言趣味教程》👈 猛戳订阅!!! 0x00 引入:I/O 的概念 计算机中的输入和输出,简称 ,其中:  代表 Input,即输入。

    2024年02月09日
    浏览(37)
  • 【Linux】理解缓冲区

    我们发现 printf 和 fwrite (库函数)都输出了2次,而 write 只输出了一次(系统调用)。为什么呢?肯定和fork有关! C接口的函数被打印了两次系统接口前后只是打印了一次:和fork函数有关,fork会创建子进程。在创建子进程的时候,数据会被处理成两份,父子进程发生写时拷

    2024年01月23日
    浏览(45)
  • 【Linux】文件缓冲区

    提到文件缓冲区这个概念我们好像并不陌生,但是我们对于这个概念好像又是模糊的存在脑海中,之间我们在介绍c语言文件操作已经简单的提过这个概念,今天我们不妨深入理解什么是文件缓冲区 通过自己实现库中的一些文件操作函数更加深入的理解文件缓冲区 自定义实现

    2024年02月10日
    浏览(46)
  • 【linux】重定向+缓冲区

    自我名言 : 只有努力,才能追逐梦想,只有努力,才不会欺骗自己。 喜欢的点赞,收藏,关注一下把! close(1),为什么没有打印新建文件fd呢? printf(“%dn”,fd); printf会把内容打印到stdout文件中。 但是close(1)关闭标准输出stdout—显示器,int fd=open();新打开的文件fd是1。 st

    2024年02月08日
    浏览(38)
  • 【Linux】深入理解缓冲区

    目录 什么是缓冲区 为什么要有缓冲区 缓冲区刷新策略 缓冲区在哪里  手动设计一个用户层缓冲区 缓冲区本质上一块内存区域,用来保存临时数据。 缓冲区在各种计算任务中都广泛应用,包括输入/输出操作、网络通信、图像处理、音频处理等。 这块内存区域是由 谁提供的

    2024年02月15日
    浏览(55)
  • 浅谈linux缓冲区的认识!

    今天来为大家分享一波关于缓冲区的知识!那么既然我们要谈缓冲区,那么就得从是什么?为什么?有什么作用这几个方面来谈论一下缓冲区!然后再通过一些代码来更加深刻的理解缓冲区的知识! 从最简单的理解方面来,我们可以将缓冲区理解成一块内存!那么这块内存是

    2024年02月05日
    浏览(45)
  • 【Linux】深入理解文件缓冲区

    问题引入 首先看一段代码: 运行代码,结果如下: 如果此时将输出结果重定向一下: 会发现 printf 、 fwrite 都打印了两次。 究其原因,就要谈到缓冲区和缓冲区刷新策略的概念了。 如何理解缓冲区 假设你在青岛,你要从网上买一件商品,商家所在地是北京。你不会跑去北

    2024年02月11日
    浏览(46)
  • Linux之缓冲区的理解

    目录 一、问题引入 二、缓冲区 1、什么是缓冲区 2、刷新策略 3、缓冲区由谁提供 4、重看问题 三、缓冲区的简单实现 我们先来看看下面的代码:我们使用了C语言接口和系统调用接口来进行文件操作。在代码的最后,我们还使用fork函数创建了一个子进程。  代码运行结果如

    2024年02月03日
    浏览(40)
  • 【Linux】缓冲区+磁盘+动静态库

    缓冲区的本质就是一段用作缓存的 内存 。 节省进程进行数据IO的时间。进程使用fwrite等函数把数据拷贝到缓冲区或者外设中。 3.1、 立即刷新(无缓冲)——ffush() 情况很少,比如调用printf后,手动调用fflush刷新缓冲区。 3.2、 行刷新(行缓冲)——显示器 显示器需要满足人

    2024年02月05日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包