【C语言】Linux系统文件操作函数基本使用

Linux系统文件操作函数

包含:open close read write lseek fcntl

是Linux底层提供的API,直接和系统内核交互:

  • 无缓冲区
  • 直接操作文件描述符
  • 一切皆文件:普通文件、目录、设备、管道、socket都用这一套函数

! 说明

文件描述符

文件描述符是一个非负的整数,表示Linux内核打开的文件;

启动一个进程,默认打开三个文件描述符0-2

每次打开一个文件,系统分配一个最小的文件描述符;

内核里有一张表:进程 -> 文件描述符表 -> 指向文件结构体

需要包含的头文件:

c 复制代码
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> // open 
#include <unistd.h> // read, write, close, lseek 
#include <errno.h> // 错误码

6.1 open - 打开/创建文件

函数原型:

c 复制代码
int open(const char *pathname, int flags, mode_t mode);

作用

打开或创建一个文件,返回 文件描述符 fd (小整数)。
flags(必须掌握)

  • O_RDONLY 只读
  • O_WRONLY 只写
  • O_RDWR 读写
  • O_CREAT 文件不存在则创建
  • O_TRUNC 清空文件
  • O_APPEND 追加模式
  • O_NONBLOCK 非阻塞
  • O_BINARY 二进制(Linux 可省略)
  • O_EXCL 和 O_CREAT 一起用:文件存在则报错 (防止覆盖)
    mode(创建文件时用,权限)
    格式:0xxx 8 进制数字
  • 0644 所有者读写,其他只读
  • 0755 可执行文件
    返回值
  • 成功:文件描述符 fd(>=0)
  • 失败:-1
    示例:
c 复制代码
#include <stdio.h>
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> // open 
#include <unistd.h> // read, write, close, lseek 
#include <errno.h> // 错误码

int main()
{
	// 以只写方式发开文件,不存在则创建,权限644
	int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
	
	// 判断是否成功,open失败返回-1
	if(fd == -1){
		perror("open:");
		return -1;
	}	
	
	// 关闭文件
	close(fd);
	return 0;
}

6.2 close - 关闭文件

关闭文件描述符,释放资源。

c 复制代码
int close(int fd);

返回值

  • 成功:0
  • 失败:-1

6.3 write - 写文件

把 buf 中的数据写入文件。

c 复制代码
ssize_t write(int fd, const void *buf, size_t count);

返回值

  • 成功:实际写入字节数
  • 失败:-1
    示例:
c 复制代码
#include <stdio.h>
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> // open 
#include <unistd.h> // read, write, close, lseek 
#include <errno.h> // 错误码
#include <string.h>

int main()
{

	int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
	if(fd == -1){
		perror("open:");
		return -1;
	}	


	// 写文件
	char buff[] = "你好,C!";
	
	// 返回写入的实际字节数
	int ret = write(fd, buff, strlen(buff));

	printf("write size = %d\n", ret);

	close(fd);

	return 0;
}

6.4 read - 读文件

从 fd 读取数据到缓冲区。

c 复制代码
ssize_t read(int fd, void *buf, size_t count);

参数

fd:文件描述符

buf:存储读到的数据

count:期望读多少字节
返回值

  • 0:实际读到的字节数

  • =0:读到文件末尾(EOF)
  • -1:出错
    示例:
c 复制代码
#include <stdio.h>
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> // open 
#include <unistd.h> // read, write, close, lseek 
#include <errno.h> // 错误码
#include <string.h>

int main()
{
	// 以只读方式打开文件
	int fd = open("test.txt", O_RDONLY);
	if(fd == -1){
		perror("open:");
		return -1;
	}	


	// 读文件
	char buff[1024] = {'\0'};
	int ret = read(fd, buff, 1024); 

	printf("read size = %d, read info: %s\n", ret, buff);

	close(fd);
	return 0;
}

6.5 lseek - 移动文件的读写指针

定位文件读写位置(类似光标跳转)。

c 复制代码
off_t lseek(int fd, off_t offset, int whence);

whence

  • SEEK_SET 文件开始位置
  • SEEK_CUR 当前位置
  • SEEK_END 文件末尾

off_t offset 偏移量(正数向后,负数向前)

用途

  • 获取文件大小:lseek(fd, 0, SEEK_END)
  • 跳转到指定位置读写
    返回值
  • 成功:返回 新的光标位置(距离文件开头多少字节)
  • 失败:返回 -1
    用法:
  • 把光标移到 文件开头
c 复制代码
lseek(fd, 0, SEEK_SET);
  • 把光标移到 文件末尾
c 复制代码
lseek(fd, 0, SEEK_END);
  • 获取 文件大小(最经典用法)
c 复制代码
off_t size = lseek(fd, 0, SEEK_END); 
printf("文件大小:%ld 字节\n", size);
  • 扩展文件大小(创建空洞文件)
c 复制代码
// 把文件扩展到 1024 字节 
lseek(fd, 1024, SEEK_SET); 
write(fd, "a", 1); // 必须写一个字节才真正扩展

! 注意

  • read /write 会自动让光标向后移动,读多少字节,光标自动后移多少;
  • lseek 不会修改文件内容,只改光标位置;
  • 光标可以移到文件末尾之外 → 形成空洞文件
  • 管道、socket、终端设备 不能用 lseek(会报错)

示例:

c 复制代码
#include <stdio.h>
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> // open 
#include <unistd.h> // read, write, close, lseek 
#include <errno.h> // 错误码
#include <string.h>

int main()
{

	int fd = open("test.txt", O_RDWR | O_CREAT, 0644);
	if(fd == -1){
		perror("open:");
		return -1;
	}	


	// 写文件
	char buff[1024] = "Hello Rocky Linux!";
	int ret = write(fd, buff, 1024);	

	// 写文件会移动文件指针,将文件指针移动带开始位置再读取
	lseek(fd, 0, SEEK_SET);
	memset(buff, 0, 1024);	

	// 读文件
	ret = read(fd, buff, 1024); 

	printf("read size = %d, read info: %s\n", ret, buff);

	close(fd);
	return 0;
}
相关推荐
aaaameliaaa6 小时前
字符函数和字符串函数
c语言·笔记·算法
夜月yeyue6 小时前
AUTOSAR CP 从上电到 Runnable
c语言·网络·tcp/ip·车载系统
lsh曙光6 小时前
延时at指令和定时cron指令
linux·服务器·网络
圆山猫6 小时前
[Virtualization](四):Linux KVM/RISC-V 的 vCPU 运行路径
java·linux·risc-v
似的8357 小时前
一步一步学习使用FireMonkey动画() 使用TAnimator类创建动画
linux·学习·nginx
白白白小纯8 小时前
算法篇—反转链表
c语言·数据结构·算法·leetcode
我不管我就要叫小猪8 小时前
嵌入式Linux----网络通信
linux·运维·服务器
小羊先生car8 小时前
RTOS-F429-HAL-绝对延时和相对延时(2026/7/31)
c语言·rtos
泡沫冰@9 小时前
ECS 的介绍和使用
linux·服务器·网络
姜太小白9 小时前
【Linux】df -h 卡住问题的通用排查与解决方案总结
linux·运维·php