linux应用——文件IO和标准IO
我们都知道linux下一切皆文件的概念那么具体的运行机制是如何的呢为什么通过操作文件即可操作对应的硬件而具体的过程如下Linux 通过 VFS虚拟文件系统将硬件设备抽象为文件接口。当用户通过文件描述符fd发起系统调用时内核通过 fd 找到对应的struct file和inode从 inode 中提取设备号并在内核驱动表中找到已注册的struct file_operations。随后内核调用该结构体中对应的函数如.read/.write由该函数通过驱动配置操作硬件控制器进行数据收发。硬件本身的初始化由驱动加载或open时完成。因为有这么一整套完整的运行机制所以内核就只需向外暴露一个文件的接口供给用户使用就可以那么我们接下来就具体说一说对应的文件的操作。一.文件IO1.介绍IO自如其名 指input输入和output输出文件IO是操作系统内核直接提供的、基于“文件描述符fd”的、无用户态缓冲区的底层输入输出接口在Linux下通常指POSIX(可移植操作系统接口)标准的系统调用他是直接基于文件描述符fd的接口是用户能触及内核的最短路径无用户态缓存所以实时性会很强我们在需要高实时性和更底层的操作时会用到很多比如网络编程。他有几个特点不提供缓冲机制每次读写操作都引起系统调用核心概念是文件描述符fd访问各种类型文件Linux下,标准IO基于文件IO实现2.文件描述符fd文件描述符文件描述符是一个非负整数如 3, 4, 5...它是操作系统内核为了高效管理已被打开的文件而分配给进程的一个索引号。每一个打开的文件都对应一个文件描述符文件IO就是通过这个描述符完成的文件描述符是从0开分配的依次递增0, 1, 2表示标准输入标准输出错误3.文件打卡与关闭下面我们来深入接触一下系统提供的文件IO的函数接口#include fcntl.hint open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);第一个参数pathname是文件的路径名称第二个参数flags是指对文件的操作类型比如只读只写等第三个参数是对文件的权限管理只有在新建文件时有效这里插入一下在linux中通过 ll 命令我们可以查看文件的详细信息如下-rw-rw-r--1 kickpi kickpi 0 Jul 31 19:37 test.txt我们可以看到对于test.txt文件的第一列-rw-rw-r--有此文件的类型权限信息等-rw-这几个从左到右分别是指文件类型和用户组user权限r读取w写入 最后一个是执行权限-就是没有执行权限x就是有执行权限。rw-这几个是所属组Group权限可读可写不可执行r--这几个是其他用户权限我们经常会看到给文件赋予权限的命令chmod 666 test.txt就是改变这几个参数666对应用户组所属组合其他用户组。至于数字比如说用户组rw-就是按二进制来算-是0w是010对应2r是100对应4 所以这个数就是0246.其他同理。好了接着我们回归整体介绍文件IO的操作详细说一说第二个参数的flags使用使用多个参数可以用 | 符号结合O_RDONLY以只读方式打开文件。O_WRONLY以只写方式打开文件。O_RDWR以读写方式打开文件。O_CREAT如果文件不存在则创建它。使用此标志时必须提供第三个参数mode来指定新文件的权限。O_TRUNC如果文件已存在且以写方式打开则将其长度截断为0清空内容。O_APPEND以追加方式打开。每次执行write写入时数据都自动添加到文件末尾。O_EXCL与O_CREAT同时使用时如果文件已存在则打开失败。这可用于测试文件是否存在且该操作是原子的。O_NONBLOCK以非阻塞方式打开文件。用于设备文件、FIFO或Socket等。如果资源不可用open调用会立即返回而不会让程序一直等待。O_SYNC使每次write操作同步进行即等待物理I/O操作完成后才返回。这会确保数据被写入磁盘但会降低性能。O_NOCTTY如果pathname指向一个终端设备则不会将该设备分配为进程的控制终端。O_DIRECTORY如果pathname不是目录则open调用失败。O_NOFOLLOW如果pathname是一个符号链接则open调用失败关闭文件的函数#include unistd.hint close(int fd);参数fd是文件描述符。成功时返回0错误时返回-1。下面给出示例代码// 示例代码使用文件IO打开、创建、关闭文件 #include stdio.h // 标准输入输出头文件 #include unistd.h // POSIX操作系统API头文件包含close函数 #include errno.h // 错误号定义头文件 #include fcntl.h // 文件控制选项头文件包含open函数和标志 int main() { // 打开或创建文件./test.txt以读写模式如果文件不存在则创建权限为0666 int fd open(./test.txt, O_RDWR | O_CREAT, 0666); // 检查文件描述符是否有效open失败返回-1 if (fd -1) { // 打印错误信息 printf(%s, strerror(errno)); return -1; // 返回错误代码 } // 打印成功打开的文件描述符值 printf(fd %d\n, fd); // 关闭文件描述符释放资源 close(fd); return 0; // 程序正常退出 }输出结果如下fd34.文件的写入读取等#include unistd.hssize_t write(int fd, void *buf, size_t count);这是文件的写入其中buf是写入数据的缓存区count是写入数据的大小ssize_t read(int fd, void *buf, size_t count);这是文件的读取其中buf是接受数据的缓存区count是读取数据大小count要小于buf。其次是读取的时候要留一位给换行符。读取和写入都设计要一个概念就是文件偏移量后移就是指无论你写入数据还是读取数据都会把指向文件内容的位置移动到最后一个处理的字符那里所以要使用文件定位函数#include unistd.hoff_t lseek(int fd, off_t offset, intt whence);第三个参数whence是锁定开始移动的位置第二个参数offset是移动多少字节这个函数可以帮助我们调整目前文件内容所在的位置。下面是第三个参数的具体值和含义SEEK_SET0文件开头绝对定位。offset必须 0。把书签直接插到指定的页数。SEEK_CUR1当前位置相对定位。offset可正可负。书签从当前页开始往前或往后翻指定的页数。SEEK_END2文件末尾相对定位。offset通常为负数往后退也可以为正数制造空洞。书签从最后一页的末尾开始往前退。看代码#include stdio.h#include unistd.h#include errno.h#include fcntl.hint main(){int fd open(./test.txt,O_RDWR|O_CREAT,0666);char buf[12] {0};if(fd-1){printf(%s,strerror(errno));return -1;}if(write(fd,hello world,sizeof(hello world))0){printf(%s,strerror(errno));return -1;}lseek(fd, 0, SEEK_SET);int ret read(fd,buf,sizeof(buf));if(ret0){printf(%s,strerror(errno));return -1;}printf(fd%d\n,fd);printf(buf%s\n,buf);close(fd);return 0;}输出$ make runfd3bufhello world这就是完整的打开写入调整位置读取关闭文件的流程了解这些就差不多了还有一些其他的函数有特定的功能我放在文章最后的链接里可以自行查看二.标准IO标准IO和文件IO是有区别的他是基于文件IO用ANSI C标准进行定义的加入了用户缓存区这一环节正是有这个缓存机制减少了系统的调用环节能实现更高的效率c语言中的stdio.h就是其标准库。标准IO的操作是用一个FILE结构体来存放文件信息的他会将信息先存入用户态缓存区到达一定的数据量后再推送出去这样的操作就像流操作所以标准IO又被称为 流 。如下FILE结构体的定义#ifndef _FILE_DEFINEDstruct _iobuf {char *_ptr;int _cnt;char *_base;int _flag;int _file;int _charbuf;int _bufsiz;char *_tmpfname;};typedef struct _iobuf FILE;下面我们说一说关于多出来的这个缓存区缓冲区不是虚无缥缈的概念它就是 C 库glibc为每个FILE *流在用户态内存堆上分配的一块连续的字符数组比如 8192 字节。当使用标准IO的写入函数fwrite时会先将写入的数据存入缓存区达到一定条件时才会调用系统IO函数来进行系统调度这时候有几种机制有几个指针_IO_write_base指向缓冲区的起始地址。_IO_write_ptr指向当前可写入的位置。数据从这里开始存放。_IO_write_end指向缓冲区的末尾地址模式 场景 解释全缓冲_IOFBF_IO_write_ptr _IO_write_end写满或者程序正常exit/fclose满了才调用write。默认用于普通磁盘文件。行缓冲_IOLBF写入的数据里包含\n换行符或者写满遇到回车就调用write。默认用于终端stdout。注意如果缓冲区满了但没换行也会刷。无缓冲_IONBF_IO_write_ptr根本不用缓冲区长度为 0每次fwrite直接调用write数据不经过用户态缓存。默认用于stderr。stdin/stdout默认是行缓冲stderr没有缓冲1.文件的打开关闭FILE *fopen (const char *path, const char *mode);path是文件路径和文件名mode是和文件IO一样指定打开文件的形式模式字符串文件不存在时文件存在时读写位置偏移量核心用途r(只读)报错返回 NULL正常打开文件开头必须文件已存在只读不写如读取配置文件。w(只写)创建新文件清空为 0 字节内容全丢文件开头从头开始写覆盖旧内容危险操作类似O_TRUNC。a(追加)创建新文件保留原有内容文件末尾所有写入的数据自动追加到文件末尾类似O_APPEND不能回头改旧数据。在基础后面加上 表示可读可写r报错返回 NULL正常打开不清空文件开头用于“修改现有文件”的场景读旧数据写新数据覆盖。注意读写切换时必须fseek或fflush否则容易混乱。w创建新文件清空为 0 字节文件开头用于“从头创建并读写”。相当于先清空再读写。a创建新文件保留原有内容文件末尾读时从开头读写时强制末尾读可以从开头看但写永远跳到末尾追加还有一个b参数 ,他是为了阻止 C 库在\n和\r\n之间做多余的事可以保证读取写入的正确性在windows系统中\r 代表回到行首 \n代表向下平移到下一行\r\n结合就是到下一行行首如果没用参数bwindows系统下可能对\n做处理把他转换成\r\n会引起歧义。linux只有\n不会引起歧义。做移植的时候就必须加这个参数了int fclose(FILE *stream)成功返回0失败返回EOF-12.读写文件操作读取#include stdio.hint fgetc(FILE *stream);int getc(FILE *stream); //宏int getchar(void);fgetc是读取流的一个字符getc也是读取流的一个字符但是他是宏getchar是获取输入的字符与fgetc(stdin)一样char *fgets(char *s, int size, FILE *stream);这个是读取整行数据的写入int fputc(int c, FILE *stream);int putc(int c, FILE *stream);int putchar(int c);成功时返回写入的字符出错时返回EOF(-1)这几个函数都是写入单个字符的int puts(const char *s); int fputs(const char *s, FILE *stream);puts将缓冲区s中的字符串输出到stdout并追加’\n’fputs将缓冲区s中的字符串输出到stream,不追加 ‘\n’再介绍这两个函数高效读写size_t fread(void *ptr, size_t size, size_t n, FILE *fp);size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);参数含义通俗理解ptr内存缓冲区指针读取时数据放这里fread写入时数据从这里取fwrite。size每个元素的大小字节数比如你要存int这里就填sizeof(int)要存char就填1。nmemb要读/写的元素个数你想一次性处理多少个元素。stream文件流指针fopen返回的FILE*。fread和fwrite是标准I/O中“批量数据搬运工”。相比于fgetc一次一个字符和fputs一次一行它们直接操作内存块非常适合读写二进制数据如结构体、数组、图片数据或大块文本。接着补充对于文件内容位置操作的函数函数原型移动基准返回值是否清除feof/ferror是否支持超大文件 (2GB)rewindvoid rewind(FILE *fp);固定到开头无 (void)是隐式清除是内部使用fsetpos或 64位偏移fseekint fseek(FILE *fp, long offset, int whence);SEEK_SET/CUR/END 任意偏移量成功0失败-1否标志保留否long在32位系统限制2GBftelllong ftell(FILE *fp);获取当前位置成功返回偏移量失败返回-1L不影响标志否同样受long大小限制fgetposint fgetpos(FILE *fp, fpos_t *pos);获取当前位置存入pos成功0失败非0不影响标志是fpos_t设计支持大文件fsetposint fsetpos(FILE *fp, const fpos_t *pos);设置到pos指定的位置成功0失败非0否标志保留是fpos_t设计支持大文件到这里就差不多了这里在附上基本操作的代码#include stdio.h#include unistd.h#include errno.h#include fcntl.hint main(){FILE *fpfopen(test.txt,r);if(fpNULL){perror(fopen);return -1;}fputs(wsyunnand,fp);rewind(fp);int buf;buffgetc(fp);if(buf!EOF){printf(read:%c\n,buf);}char read[100] {0};int ifread(read,1,100,fp);printf(read all:%d,i);printf(read all:%s,read);fclose(fp);return 0;}文件内容是这个wsyunnandyeyeyessssssssssssddddddddd输出$ make runread:wread all:39read all:syunnandyeyeyessssssssssssddddddddd最后把一些其他标准IO和文件IO的一些其他函数放在这个链接linux标准IO和文件IO函数-CSDN博客

相关新闻

GPT-6免费实测:多模态、推理与上下文升级全解析

GPT-6免费实测:多模态、推理与上下文升级全解析

1. 这次升级到底改了啥:从"能用"到"好用"的三处关键变化GPT-6 全面上线,海外和国内技术圈都在刷屏。最让我这种普通用户兴奋的不是"又变聪明了"这种口号,而是免费用户这次真的能上手用了,不用开订阅…

2026/10/19 11:58:13 阅读更多 →
Lap开源本地照片管理器:免费搭建本地照片库,分钟级离线搜图

Lap开源本地照片管理器:免费搭建本地照片库,分钟级离线搜图

Lap开源本地照片管理器:免费搭建本地照片库,分钟级离线搜图 【免费下载链接】lap An offline-first photo manager for large local libraries 项目地址: https://gitcode.com/GitHub_Trending/lap3/lap 如果你家里的照片堆在硬盘里找不到头&…

2026/10/19 11:58:13 阅读更多 →
2.4GHz下LoRa与FLRC实测对比:速度与距离的工程取舍

2.4GHz下LoRa与FLRC实测对比:速度与距离的工程取舍

搞无线数传这些年,我一直对 2.4GHz 频段下 LoRa 和 FLRC 这两种调制方式的“速度与距离”取舍很感兴趣。手头这块 LoRa2021 模块刚好同时支持两种模式,趁着连续晴天,我带着两台设备、两套天线和一堆电池,在河堤上做了一轮比较完整…

2026/10/19 11:58:13 阅读更多 →

最新新闻

提示词工程实战:从基础结构到调试技巧一次讲透

提示词工程实战:从基础结构到调试技巧一次讲透

聊点实际的。最近这一年,只要跟文字处理沾点边的人,多少都跟大模型打过交道。但同样面对同一款对话模型,有人三言两语就能问出高质量方案,有人翻来覆去只能得到一堆正确的废话。差别往往不在模型,而在你怎么把需求说清…

2026/10/19 16:36:20 阅读更多 →
IDEA一肩挑:Python+Java双语言自动化框架搭建全攻略

IDEA一肩挑:Python+Java双语言自动化框架搭建全攻略

很多做自动化测试或者开发内部工具的朋友,都会遇到一个绕不开的纠结:项目到底用 Python 还是 Java。选 Python,团队里的 Java 老手写起来浑身别扭;选 Java,临时脚本和数据处理又笨重得想骂人。其实真没必要二选一。IDE…

2026/10/19 16:36:20 阅读更多 →
LangChain实战指南:大模型应用开发核心模块与避坑经验

LangChain实战指南:大模型应用开发核心模块与避坑经验

作为常年泡在 AI 应用开发一线的工程师,我这两年接手的项目里,十个有八个都跟大模型相关。刚开始那会儿,大家都是在代码里直接拼一个 HTTP 请求去调各家模型的 API,今天发现甲家的理解能力强,明天发现乙家的响应快&…

2026/10/19 16:36:20 阅读更多 →
PPA注意力模块提升YOLO小目标检测的PyTorch实现与集成实战

PPA注意力模块提升YOLO小目标检测的PyTorch实现与集成实战

小目标检测一直是YOLO系列的老大难问题。很多时候你的模型在常规目标上指标涨得挺欢,一到小物体上就开始拉胯,原因往往不是特征提取不够充分,而是注意力机制在“看”一个只有十几像素的小目标时,把全局的上下文平均了一下&#xf…

2026/10/19 16:36:20 阅读更多 →
IDEA整合Java与Python:多语言自动化测试框架搭建实战教程

IDEA整合Java与Python:多语言自动化测试框架搭建实战教程

如果你所在的团队既有基于 Java 的 UI 自动化框架,又有用 Python 写的接口自动化脚本,那你大概率经历过这种拧巴:平时开一个 IDEA 写 Java 用例,跑 Python 脚本还要切到 PyCharm,两个项目各存一份环境配置,…

2026/10/19 16:36:20 阅读更多 →
基于Git钩子的CLI代码评审工作流:LLM+open-code-review实战

基于Git钩子的CLI代码评审工作流:LLM+open-code-review实战

1. 项目概述:这不是一个工具,而是一套可落地的代码评审新工作流“open-code-review”这个名称乍看像某个开源项目仓库名,但结合当前技术热点和实际工程痛点,它本质上指向一种正在快速成型的新型代码评审范式——以开源精神重构代码…

2026/10/19 16:35:07 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →