news 2026/8/12 15:19:14

linux标准IO和文件IO函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
linux标准IO和文件IO函数

一 .文件IO系列

第一组:文件属性获取(stat/fstat/lstat

头文件#include <sys/stat.h>#include <unistd.h>

1.int stat(const char *pathname, struct stat *statbuf);

  • 功能:通过文件路径获取文件属性,会追踪软链接(指向源文件)。

  • 参数

    • pathname:字符串,要查询的文件路径(如"./test.txt")。

    • statbuf输出型参数,指向struct stat结构体的指针。内核会把文件大小、权限、时间等信息填充到这个结构体中。

  • 返回值:成功返回0,失败返回-1(并设置errno)。

2.int fstat(int fd, struct stat *statbuf);

  • 功能:通过文件描述符获取文件属性(无需路径)。

  • 参数

    • fd:已打开的文件描述符(由open返回)。

    • statbuf:同上,输出型参数。

  • 返回值:成功返回0,失败返回-1

3.int lstat(const char *pathname, struct stat *statbuf);

  • 功能:通过文件路径获取文件属性,不会追踪软链接(查的是链接文件本身,不是它指向的目标)。

  • 参数:同stat

  • 返回值:成功返回0,失败返回-1


第二组:目录流操作(opendir/readdir/closedir

头文件#include <dirent.h>

4.DIR *opendir(const char *name);

  • 功能:打开一个目录,建立目录流(相当于针对目录的open)。

  • 参数

    • name:目录路径字符串(如"."当前目录,"/home")。

  • 返回值:成功返回目录流指针DIR*,失败返回NULL(并设置errno)。

5.struct dirent *readdir(DIR *dirp);

  • 功能:从已打开的目录流中,逐条读取下一个目录项(一个文件或子目录)。

  • 参数

    • dirp:由opendir返回的目录流指针。

  • 返回值:成功返回指向struct dirent结构体的指针(该结构体里有文件名d_name),读到末尾或出错时返回NULL(用errno区分是结束还是出错)。

  • 重要细节:每调用一次,自动往后移一个条目。

6.int closedir(DIR *dirp);

  • 功能:关闭目录流,释放相关资源。

  • 参数dirp:要关闭的目录流指针。

  • 返回值:成功返回0,失败返回-1


第三组:文件描述符复制(dup/dup2

头文件#include <unistd.h>

7.int dup(int oldfd);

  • 功能:复制一个文件描述符。新描述符指向内核中同一个文件对象(共享偏移量和锁)。

  • 参数

    • oldfd:要被复制的旧文件描述符。

  • 返回值:成功返回新的文件描述符(系统自动分配当前最小的可用数字),失败返回-1

8.int dup2(int oldfd, int newfd);

  • 功能:复制oldfd,但强制把newfd作为新的副本编号。如果newfd已被打开,内核会先静默关闭它,再让它指向oldfd的文件对象。

  • 参数

    • oldfd:旧文件描述符。

    • newfd:你指定的新文件描述符编号(如1)。

  • 返回值:成功返回newfd,失败返回-1


第四组:文件控制万能锁(fcntl

头文件#include <fcntl.h>#include <unistd.h>

9.int fcntl(int fd, int cmd, ... /* arg */);

  • 功能:对已打开的文件描述符执行各种控制操作(修改标志、复制 fd、加锁等)。这是一个可变参数函数。

  • 参数

    • fd:要操作的文件描述符。

    • cmd:操作命令(必填),常见取值:

      • F_GETFL:获取文件状态标志(如是否阻塞)。此时不需要第三个参数

      • F_SETFL:设置文件状态标志。此时第三个参数arg必须传入新的标志(如O_NONBLOCK)。

      • F_DUPFD:复制 fd,此时第三个参数arg指定新 fd 的最小可用数字(类似dup的加强版)。

      • F_SETLK/F_SETLKW:设置记录锁,此时第三个参数必须是struct flock*指针。

    • ...arg(可选),取决于cmd

  • 返回值:取决于cmd

    • F_GETFL成功返回标志值(整数);

    • 其他命令成功返回0

    • 统一失败返回-1


第五组:删除目录项(unlink

头文件#include <unistd.h>

10.int unlink(const char *pathname);

  • 功能:从文件系统中删除一个名字(目录项)。当文件的硬链接数减为 0 且没有进程打开它时,磁盘空间才会被释放(这是rm命令的底层实现)。

  • 参数

    • pathname:要删除的文件路径字符串。

  • 返回值:成功返回0,失败返回-1


第六组:检查文件权限(access

头文件#include <unistd.h>

11.int access(const char *pathname, int mode);

  • 功能:以调用进程的真实用户 ID 和组 ID来检查对文件的访问权限(常用于在真正open前做预判)。

  • 参数

    • pathname:文件路径。

    • mode:要检查的权限位(只能传以下宏之一):

      • F_OK:检查文件是否存在。

      • R_OK:检查是否可读。

      • W_OK:检查是否可写。

      • X_OK:检查是否可执行。

  • 返回值:允许(满足权限)返回0,拒绝(不满足)或出错返回-1


第七组:截断/扩展文件大小(truncate/ftruncate

头文件#include <unistd.h>#include <sys/types.h>

12.int truncate(const char *path, off_t length);

  • 功能:通过文件路径将文件大小设置为length字节。如果原文件大于length,尾部被丢弃;小于length,文件被扩展(中间会形成“空洞”,不占物理磁盘空间)。

  • 参数

    • path:文件路径字符串。

    • length:目标长度(字节数,off_t类型)。

  • 返回值:成功返回0,失败返回-1

13.int ftruncate(int fd, off_t length);

  • 功能:通过文件描述符将文件大小设置为length字节(功能同truncate,但操作的是已打开的文件)。

  • 注意:该文件必须以可写方式打开(O_WRONLYO_RDWR)。

  • 参数

    • fd:已打开的文件描述符。

    • length:目标长度。

  • 返回值:成功返回0,失败返回-1

二 . 标准IO系列

第一组:状态判断(feof/ferror/clearerr

头文件#include <stdio.h>

1.int feof(FILE *stream);

  • 作用:检查文件流是否到达了文件末尾

  • 参数stream—— 文件流指针。

  • 返回值:如果已到达文件末尾,返回非零值(真);否则返回0(假)

  • 陷阱feof不会在刚读完最后一个字符时返回真,而是在你尝试越过末尾再读一次后才会返回真。所以千万不要用它来做循环终止条件(正确姿势是while(fread(...) > 0),循环结束后再判断feof)。

2.int ferror(FILE *stream);

  • 作用:检查文件流是否发生了 I/O 错误

  • 参数stream—— 文件流指针。

  • 返回值:如果发生了错误,返回非零值(真);否则返回0(假)

  • 场景:当freadfgetc返回异常值时,用ferror区分“读到末尾”和“读取出错”。

3.void clearerr(FILE *stream);

  • 作用清除文件流的文件结束标志(EOF)错误标志

  • 参数stream—— 文件流指针。

  • 返回值:无(void)。

  • 场景:当你处理完一个错误,或者用rewind重置位置后,需要手动清除标志,否则后续的读写操作会被阻塞。


第二组:大文件位置控制(fgetpos/fsetpos

头文件#include <stdio.h>

4.int fgetpos(FILE *stream, fpos_t *pos);

  • 作用:获取当前文件流的位置指示器,存入pos结构体中(支持超大文件 >2GB)。

  • 参数

    • stream:文件流指针。

    • pos:输出型参数,指向fpos_t类型变量的指针,用来接收位置值。

  • 返回值:成功返回0,失败返回非零值(并设置errno)。

5.int fsetpos(FILE *stream, const fpos_t *pos);

  • 作用:将文件流的位置指示器设置到pos指定的位置(通常与fgetpos配合使用)。

  • 参数

    • stream:文件流指针。

    • pos:输入型参数,指向之前用fgetpos获取的fpos_t值。

  • 返回值:成功返回0,失败返回非零值

  • fseek的区别fpos_t可以存储复杂的文件状态,在超大文件(>2GB)和特殊文件系统上表现更安全。


第三组:缓冲区强制刷新(fflush

头文件#include <stdio.h>

6.int fflush(FILE *stream);

  • 作用:强制将用户态缓冲区中未写入的数据刷入内核(调用write)。

  • 参数

    • stream:文件流指针。如果传NULL,则刷新所有已打开的流的输出缓冲区。

  • 返回值:成功返回0,失败返回EOF(并设置errno)。

  • 注意fflush只保证数据到达内核页缓存,不保证落盘。想落盘需调用fsync(fileno(fp))


第四组:(fileno/fdopen

头文件#include <stdio.h>(在 Linux 下,filenofdopen也依赖<unistd.h><fcntl.h>)

7.int fileno(FILE *stream);

  • 作用:从标准I/O流(FILE*)中,掏出底层的文件描述符(fd)

  • 参数stream—— 文件流指针。

  • 返回值:成功返回底层的int fd,失败返回-1

  • 场景:当你用fopen打开了文件,但突然想用fcntl加锁,或者用fsync强制落盘时,必须靠它取出fd

8.FILE *fdopen(int fd, const char *mode);

  • 作用:将一个已有的文件描述符(fd),包装成一个标准I/O流(FILE*)。

  • 参数

    • fd:已打开的文件描述符(来自opensocket)。

    • mode:字符串,和fopen一样(如"r""w+")。必须fd打开时的模式兼容(比如fd是只读的,就不能传"w")。

  • 返回值:成功返回FILE*指针,失败返回NULL

  • 场景:网络编程中,你从socket()拿到了fd,但想用fprintf格式化输出数据,就可以用它包装。


第五组:安全字符串格式化(snprintf/sscanf

头文件#include <stdio.h>

9.int snprintf(char *str, size_t size, const char *format, ...);

  • 作用:将格式化数据写入字符串,并保证不超过指定长度,末尾自动添加'\0'(防止缓冲区溢出)。

  • 参数

    • str:目标字符串缓冲区。

    • size:缓冲区的最大长度(包含结尾的'\0')。

    • format:格式化字符串(同printf)。

    • ...:可变参数列表。

  • 返回值如果缓冲区足够大,返回本应写入的字符数(不包括结尾的'\0');如果返回值>=size,说明数据被截断了。

  • 铁律永远用snprintf替代不安全的sprintf

10.int sscanf(const char *str, const char *format, ...);

  • 作用:从字符串str中,按照format格式提取数据,存入后面的变量中。

  • 参数

    • str:源字符串(通常来自fgets读的一行)。

    • format:格式字符串(同scanf)。

    • ...:目标变量的地址(带&)。

  • 返回值:成功匹配并赋值的参数个数(可用于校验读取是否成功)。如果返回0EOF,说明格式不匹配。

  • 工程组合fgets读一行 +sscanf解析 => 最安全的配置文件/CSV 读取方式,避免fscanf直接操作文件流可能导致的卡死或位置错乱。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/12 15:18:24

深入解析JVM对象创建与内存分配机制

1. JVM对象创建与内存分配机制概述 在Java开发者的日常工作中&#xff0c;JVM对象创建与内存分配机制就像空气一样无处不在却又容易被忽视。直到某天你的应用突然出现OOM异常&#xff0c;或者GC日志开始频繁报警&#xff0c;才会真正意识到理解这些底层机制的重要性。我经历过多…

作者头像 李华
网站建设 2026/8/12 15:16:25

RAG技术详解:从检索增强生成原理到企业级应用实战

1. 项目概述&#xff1a;从“拍脑袋”到“有据可依”的智能问答如果你最近在折腾大语言模型&#xff08;LLM&#xff09;的应用&#xff0c;大概率会碰到一个场景&#xff1a;你问它一个非常具体、需要最新或私有知识的问题&#xff0c;比如“我们公司上季度某产品的销售数据趋…

作者头像 李华
网站建设 2026/8/12 15:16:03

位运算在算法中的应用:解决只出现一次的数字问题

1. 问题背景与核心需求 第一次在LeetCode上看到"只出现一次的数字"这道题时&#xff0c;我正处在刷题初期阶段。这道编号为136的题目看似简单&#xff0c;却暗藏玄机。题目要求&#xff1a;给定一个非空整数数组&#xff0c;除了某个元素只出现一次外&#xff0c;其余…

作者头像 李华
网站建设 2026/8/12 15:15:09

8.9华为OD机试真题 新系统 - 查找最佳充电策略 (Java/Py/C/C++/Js/Go)

查找最佳充电策略 2026 华为OD机试真题8月9日华为OD上机新系统考试真题 100 分题型 点击查看华为 OD 机试真题完整目录&#xff1a;2026最新华为OD机试新系统卷 双机位C卷 真题题库目录&#xff5c;全覆盖题库 逐点算法考点详解 题目描述 给定一个一维数组 priceArray&…

作者头像 李华
网站建设 2026/8/12 15:11:54

2024国内AI大模型选型实战:八大模型核心能力与场景匹配指南

1. 从“能用”到“好用”&#xff1a;2024年国内AI大模型选型实战最近和几个做产品、搞开发的朋友聊天&#xff0c;发现大家现在选AI大模型&#xff0c;心态已经从去年的“哪个能用”变成了“哪个好用”。去年是只要能跑通API、别总报错就行&#xff0c;今年不一样了&#xff0…

作者头像 李华