当前位置: 首页 > news >正文

文件-语言-系统:基础IO-2.0——IO重定向接口,语言层缓冲区,系统级缓冲区。内核级分析!

bit::Shadow✧(≖ ◡ ≖✿目录重定向接口dup2() 函数原型输出重定向1和2的使用文件描述符表./a.out运行./a.out 默认重定向是fd 1合并标准输入输出缓冲区什么是缓冲区缓冲区的意义语言与系统中的缓冲区语言级文件操作fd未提前关闭fd提前关闭系统调用接口较于库函数的强关联性为什么stdout下write在最后打印到文件内却是第一个打印呢父子进程分别退出导致语言层缓冲区双倍刷新原因为什么设计“语言层”与“系统层”缓冲区分离的机制衔接上篇文件IO-1.0重定向接口dup2() 输出重定向清空并新写入。追加重定向追加内容到指定文件/流。输入重定向例cat log.txt 就是 cat log.txt 。标准输出1与标准错误2指向的均是标准错误不过fd不同。函数原型int dup2(int oldfd, int newfd);功能基于操作系统“只认文件标识符fd”来定位输出对象的前提让newfd指向oldfd指向的文件/设备成功则返回新fd否则返回-1。当我们进行以fd标识的输入输出读取等操作时就会因为fd的重定向导致操作对象改变例dup2(fd, 1); //将标准输出流内的数据写入到fd指向的文件内。int main() { int fd open(log.txt, O_WRONLY | O_CREAT | O_TRUNC, 0666); //fd 3 dup2(fd, 1); printf(预备标准输出流内容\n); const char* s nihao\n; write(fd, s, strlen(s)); close(fd); return 0; }运行发现显示器并未出现“预备标准输出流内容”的输出而是文件log.txt内被写入。由此也可以体现Linux作为独立于Win操作系统的存在正是其操作系统默认打开的0标准输入流1标准输出流及2标准错误流。文字/符号/图形才得以显示。输出重定向1和2的使用文件描述符表OS只识别文件fd☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆1标准输出流2标准错误流两者均是像显示器打印。运行以下代码#include cstdio #include iostream int main() { //向标准输出进行打印stdoutcin-1 std::cout hello cout std::endl; printf(hello printf\n); //向标准错误进行打印stderrcerr-2, std::cerr hello cerr std::endl; fprintf(stderr, hello stderr\n); return 0; }./a.out运行./a.out 默认重定向是fd 1err内容输出到屏幕./a.out 2 合并标准输入输出./a.out log.txt 2 1错误方式./a.out log.txt 2 1缓冲区什么是缓冲区简单理解缓冲区是一块内存区域。缓冲区的意义尽量集中数据、同时处理提高交互效率。语言与系统中的缓冲区语言层系统层分别有自己的缓冲区两者缓冲区的关系是各自独立但间接相关。语言级缓冲区刷新条件1.强制刷新。如fflush()函数2.满足特定条件自动刷新。例缓冲区满、行刷新/行缓冲“\n”。3.进程退出。如程序结束、exit(-1)强制退出。文件操作语言对文件的操作本质是系统对磁盘的IO管理因此涉及到语言层缓冲区与系统层缓冲区的交互。非全缓冲是行缓冲一般缓冲语言缓冲区到系统缓冲区传递条件fd文件标识符 系统调用像write()printf/fprintf/fwrite/fputs均是库函数本质内部均封装“write”。也就是说若fd使用close提前关闭就会输出混乱。fd未提前关闭fd提前关闭语言采用行刷新后关闭不会输出在fd原因及解决方案\n触发行缓冲刷新是C 标准 I/O 行为而不是文件描述符的概念前提是stdout被终端关联且缓冲模式是行缓冲。如果你发现log.txt没有内容说明stdout在程序启动时就不是行缓冲例如被重定向或从非终端启动应使用fflush(stdout)强制刷新。系统调用接口较于库函数的强关联性write为例将buf内容写到fd指向的文件内#include unistd.h ssize_t write(int fd, const void *buf, size_t count);显示器与文件操作下的对比代码void test4() { //三种库函数写入到显示器 printf(printf\n); fprintf(stdout, fprintf\n); const char* s fwrite\n; fwrite(s, strlen(s), 1, stdout); //系统调用 const char* ss write\n; write(1, ss, strlen(ss)); }显示器文件为什么stdout下write在最后打印到文件内却是第一个打印呢原因因为语言层IO想要进入文件必须经“语言---系统层面”的区域转换作用时“write系统调用”下距离OS缓冲区更近因此优于库函数写入到文件内。而呈现出虽然代码从上向下执行但系统调用优先特殊逻辑关系链。父子进程分别退出导致语言层缓冲区双倍刷新int main() { //库函数 printf (hello printf\n); fprintf (stdout, hello fprintf\n); const char *s hello fwrite\n; fwrite (s, strlen (s), 1, stdout); //系统调用 const char *ss hello write\n; write (1, ss, strlen (ss)); //??? fork(); }运行原因PCB下双层退出导致二次刷新从而形成了文件IO双倍的现象为什么设计“语言层”与“系统层”缓冲区分离的机制系统调用是操作系统亲临执行任务操作系统是最忙的存在。简而言之系统调用成本太高的像malloc时顺序表时两倍的扩容机制、vector、tcmalloc等设计均是为优化这一影响而设计出的解决方案。感谢观看求关注
http://www.rkmt.cn/news/1385256.html

相关文章:

  • Unity ML-Agents 环境配置避坑指南:Python+CUDA+Unity 版本精准匹配
  • 基于ESP32的智能电池充电器设计:多化学体系支持与模块化架构
  • FT231XQ USB串口桥接板设计解析与实战应用指南
  • 基于双T振荡器的正弦波LED调光电路设计与实践
  • ssm高校推免报名系统(10102)
  • 转行网络安全运维:从0到1的可落地指南
  • vectorizer图像矢量化工具:3步实现PNG/JPG到SVG的智能转换
  • 如何为Nintendo Switch安装游戏?Awoo Installer的3种安装方式全解析
  • Aqara G5 Pro:2026年最佳室外HomeKit摄像头推荐
  • 为什么说AI革命才刚刚开始?从技术演进到商业落地的真实变化
  • 【Qwen3.6】关键技术:线性注意力(Linear Attention/DeltaNet)和标准多头注意力(Standard Attention)混合
  • MySQL 死锁产生原因与避免
  • Hugging Face 中tokenizer.json 和vocab.json 有区别?
  • AI 充电枪智能功率 MOSFET 完整选型方案
  • 玩转Hermes Agent|使用Lighthouse快速部署云上Hermes Agent-周红伟
  • 如何精准控制20QPS测试百度首页
  • 企业数据安全方案有哪些:2026年从风险评估到落地的完整指南 - 华旭传媒
  • 博弈论导向的车辆队列运动协同分层控制算法【附算法】
  • 企业级AI语音合成采购决策白皮书(2024真实报价单首次公开)
  • RTX51 Tiny内存冲突与ISD51调试器解决方案
  • 精准测试落地难?我用半年实践总结出这4条铁律
  • 机器学习入门:理解线性回归与逻辑(简化且附Python实战代码)
  • 2026年金华为餐饮企业提供SAAS收银系统的服务商综合分析与适配指南 - 万事通达
  • Claude code 接入 deepseek-v4-pro setting 文件配置
  • HTTP与HTTPS超详解:协议流程、报文结构、HTTPS加密、各版本区别、面试
  • Visual C++运行库合集终极指南:一键解决Windows应用程序依赖问题
  • ​用于雷达系统设计的 MATLAB 仿真附matlab代码
  • 2026软考中级软件设计师_考后分享
  • 基于GMR传感器的DIY示波器电流钳探头设计与实现
  • 暗黑破坏神2存档修改器:Diablo Edit2让你的游戏体验随心所欲