Linux 系统编程入门:从文件 IO 到标准库,一篇就够

发布时间:2026/7/16 20:15:00

Linux 系统编程入门:从文件 IO 到标准库,一篇就够 一、Linux 系统编程站在系统的肩膀上开发1.1 什么是 Linux 系统编程简单说在 Linux 系统上调用系统提供的函数实现想要的功能。比如写一个音乐播放器需要从网络下载歌曲网络编程、保存到本地文件编程、多线程播放多任务编程。核心思想Linux 下一切皆文件设备、管道、Socket 都被抽象成文件用统一的文件接口操作。1.2 Linux 内核与用户空间Linux 系统被严格划分为两层内核空间Kernel管理硬件、内存、进程、网络等核心功能只有内核能直接操作硬件。用户空间User我们写的应用程序运行在这里不能直接操作硬件必须通过系统调用或库函数向内核发起请求。两种实现功能的路径直接系统调用用 Linux 原生提供的函数比如write更底层、更高效。库函数调用用封装好的库比如 C 标准库stdio更易用、跨平台。二、Linux 文件一切皆文件2.1 7 种文件类型Linux 把所有资源都抽象成文件用ls -l命令可以看到文件类型类型符号例子说明普通文件-1.txt、mp3、jpg存储数据、文本、音视频等目录文件dtest/管理文件集合字符设备c/dev/input、/dev/tty按字节流操作的设备键盘、鼠标块设备b/dev/sda按块操作的设备硬盘链接文件llibc.so - libc.so.6软链接类似 Windows 快捷方式套接字ssocket网络通信、进程间通信管道ppipe进程间通信2.2 文件操作的基本流程无论什么文件操作逻辑都一样打开 → 读/写 → 关闭打开获取文件的操作权限关联一个「流」。读 / 写操作文件数据。关闭释放资源保存数据。三、标准 IOstdio库函数的便捷操作标准 IO 是 C 标准库提供的文件操作函数封装了系统调用自带缓冲区使用更简单、效率更高。3.1 核心概念流Stream流对数据读写过程的抽象用FILE*指针表示。Linux 默认打开 3 个流stdin标准输入键盘FILE*指针。stdout标准输出屏幕。stderr标准错误输出。3.2 打开文件fopen#include stdio.h FILE *fopen(const char *pathname, const char *mode);参数pathname文件路径比如1.txt。mode打开模式决定读写行为模式含义不存在时r只读报错w只写创建清空原有内容a追加创建在末尾写入r读写报错w读写创建清空原有内容a读写创建在末尾写入返回值成功返回FILE*流指针失败返回NULL。示例FILE *fp fopen(1.txt, r); if (fp NULL) { perror(fopen failed); // 打印错误信息 return -1; }3.3 关闭文件fcloseint fclose(FILE *stream);功能关闭流释放资源刷新缓冲区。注意同一个文件只需关闭一次关闭后不能再操作。3.4 读写文件4 组核心函数1. 按字符读写fgetc/fputcint fgetc(FILE *stream); // 读一个字符 int fputc(int c, FILE *stream); // 写一个字符每次读写 1 个字符适合文本文件。到达文件末尾返回EOF-1。2. 按行读写fgets/fputschar *fgets(char *s, int size, FILE *stream); // 读一行 int fputs(const char *s, FILE *stream); // 写一行fgets最多读size-1个字符自动在末尾加\0遇到\n停止。fputs写字符串不自动加\n。3. 按对象读写fread/fwrite最通用size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); // 读 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); // 写功能读写nmemb个元素每个元素大小为size适合二进制文件、结构体。示例读写结构体struct stu { char name[20]; int id; float score; }; struct stu s {Tom, 1001, 90.5}; // 写 fwrite(s, sizeof(struct stu), 1, fp); // 读 struct stu s2; fread(s2, sizeof(struct stu), 1, fp);3.5 文件定位fseek/ftellint fseek(FILE *stream, long offset, int whence); // 移动文件指针 long ftell(FILE *stream); // 获取当前指针位置whence参考位置SEEK_SET文件开头SEEK_CUR当前位置SEEK_END文件末尾示例获取文件大小fseek(fp, 0, SEEK_END); // 移到末尾 long size ftell(fp); // 末尾位置就是文件大小3.6 标准 IO 缓冲区标准 IO 自带缓冲区分为 3 种全缓冲缓冲区满才刷新普通文件默认。行缓冲遇到\n才刷新stdout默认。无缓冲立即输出stderr默认。手动刷新int fflush(FILE *stream);四、实战用标准 IO 实现cat命令cat命令功能读取文件内容并输出到屏幕。#include stdio.h int main(int argc, char *argv[]) { if (argc ! 2) { printf(Usage: %s filename\n, argv[0]); return -1; } FILE *fp fopen(argv[1], r); if (fp NULL) { perror(fopen failed); return -1; } char buf[1024]; while (fgets(buf, sizeof(buf), fp) ! NULL) { fputs(buf, stdout); // 输出到屏幕 } fclose(fp); return 0; }五、系统 IO系统调用更底层的操作系统 IO 是 Linux 内核提供的原生函数没有缓冲区直接操作文件描述符int fd。5.1 文件描述符fd内核为每个打开的文件分配一个整数fd用来标识文件。默认打开的 3 个文件描述符0标准输入stdin1标准输出stdout2标准错误stderr5.2 核心系统调用函数功能原型open打开 / 创建文件int open(const char *pathname, int flags, mode_t mode);read读文件ssize_t read(int fd, void *buf, size_t count);write写文件ssize_t write(int fd, const void *buf, size_t count);lseek移动文件指针off_t lseek(int fd, off_t offset, int whence);close关闭文件int close(int fd);5.3 标准 IO vs 系统 IO特性标准 IOstdio系统 IOsyscall层级库函数封装系统调用内核原生函数缓冲区自带效率高无直接读写可移植性好跨平台差仅 Linux灵活性低高可精细控制六、总结与学习建议6.1 核心知识点回顾Linux 一切皆文件7 种文件类型统一操作接口。文件操作流程打开 → 读 / 写 → 关闭。标准 IOfopen/fclose/fread/fwrite自带缓冲区易用高效。系统 IOopen/close/read/write更底层直接操作文件描述符。流与文件描述符FILE*是标准 IO 的抽象int fd是系统 IO 的抽象。

相关新闻