Linux 文件操作详解:结构、系统调用、权限与实践

文章目录

  • [Linux 文件操作详解:结构、系统调用、权限与实践](#Linux 文件操作详解:结构、系统调用、权限与实践)

Linux 文件操作详解:结构、系统调用、权限与实践

关键词: Linux 文件结构、文件描述符、系统调用、read/write、open/close、权限控制、实战代码


一、为什么说"一切皆文件"

Linux 系统将万物抽象为文件:

  • 常规文件(普通文本、二进制)
  • 目录(实际上是一个特殊的文件)
  • 字符设备与块设备(如串口、硬盘)
  • 网络连接(socket)
  • 虚拟文件(如 /proc/cpuinfo

这种设计让系统 I/O 操作接口极其统一,极大提升了系统的灵活性和可扩展性。


二、Linux 文件系统结构详解

目录 功能说明
/ 根目录,所有文件系统的起点
/root 超级用户的主目录
/bin 二进制可执行程序,系统启动与常用命令
/boot 启动相关文件,如内核镜像
/dev 设备文件(如 /dev/sda 硬盘)
/etc 系统配置文件
/home 普通用户的主目录
/lib 系统核心共享库
/usr 用户程序资源(常被挂载为只读)
/var 日志、缓存等可变数据
/tmp 临时文件存储
/media 挂载的 U 盘、光盘等
/proc 虚拟文件系统,内核状态如进程信息

⚠️ /dev/proc/sys 等目录是 Linux 与硬件或内核交互的核心。


三、文件描述符(File Descriptor)

什么是文件描述符?

Linux 使用整数 fd(File Descriptor)标识每一个打开的文件资源:

  • 0:标准输入(stdin)
  • 1:标准输出(stdout)
  • 2:标准错误(stderr)

每当你调用 open() 打开一个文件时,系统都会返回一个新的最小未使用的文件描述符。

多个 fd 可指向同一文件?

是的。例如:

c 复制代码
int fd1 = open("file.txt", O_RDONLY);
int fd2 = dup(fd1);  // 复制 fd1,两个都指向同一个文件

四、两种文件操作方式对比

操作方式 示例函数 特点说明
底层系统调用 open, read, write, close 精准控制、效率高、无缓冲
标准 I/O 函数 fopen, fread, fprintf 使用方便、有缓冲区

系统调用更适合底层开发(如驱动、内核模块),标准 I/O 适合一般应用程序。


五、核心系统调用详解(附实战)

1. open 打开文件

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

常用标志位:

  • O_RDONLY, O_WRONLY, O_RDWR
  • O_CREAT:文件不存在则创建(需提供权限)
  • O_TRUNC:清空已有内容
  • O_APPEND:追加模式
  • O_EXCL:配合 O_CREAT,文件存在则报错

权限常量:

  • S_IRUSR:所有者读权限
  • S_IWUSR:所有者写权限
  • S_IRWXU:所有者读写执行权限(如 0700

示例:

c 复制代码
int fd = open("data.txt", O_RDWR | O_CREAT, 0644);

2. write 写入文件

c 复制代码
ssize_t write(int fd, const void *buf, size_t count);
  • 成功返回写入字节数,失败返回 -1。
  • 从当前文件指针开始写入。

示例:

c 复制代码
write(fd, "Hello\n", 6);

3. read 读取文件

c 复制代码
ssize_t read(int fd, void *buf, size_t count);
  • 返回值:

    • 0:读取的字节数

    • =0:文件结束
    • <0:读取出错

示例:

c 复制代码
char buf[128];
int len = read(fd, buf, sizeof(buf));

4. close 关闭文件

c 复制代码
int close(int fd);
  • 成功返回 0,失败返回 -1。
  • 释放资源,fd 变为无效。

5. lseek 移动文件指针

c 复制代码
off_t lseek(int fd, off_t offset, int whence);
  • SEEK_SET:相对于文件头
  • SEEK_CUR:相对于当前位置
  • SEEK_END:相对于文件尾部

应用:

c 复制代码
lseek(fd, 100, SEEK_SET); // 跳到偏移 100

6. ioctl 设备控制

c 复制代码
int ioctl(int fd, int cmd, ...);
  • 专用于控制设备行为
  • 不同设备支持不同的 cmd
  • 常用于串口、网络驱动、图形接口等底层控制

六、实战代码示例

文件复制程序(底层 API)

c 复制代码
int fd_in = open("source.txt", O_RDONLY);
int fd_out = open("dest.txt", O_CREAT | O_WRONLY, 0644);
char buf[1024];
int len;

while ((len = read(fd_in, buf, sizeof(buf))) > 0) {
    write(fd_out, buf, len);
}

close(fd_in);
close(fd_out);

七、性能分析:time 命令

bash 复制代码
time ./copy

输出说明:

  • real:总执行时间
  • user:用户空间耗时
  • sys:系统调用耗时

I/O 密集型程序,sys 会占比较高。


八、总结与建议

操作 场景建议
open 精细控制文件打开方式
read/write 控制读取/写入字节精度
lseek 随机读写或偏移操作
ioctl 驱动开发与设备控制
fopen/fread 高级抽象,适合应用层

技巧建议:

  • 所有 open() 后的 fd 必须在适当时机 close()
  • 处理文件写入建议加 O_APPEND 防止并发写覆盖。
  • 出错检查别忘记使用 strerror(errno) 获取具体错误信息。

拓展阅读

  • dup/dup2:复制文件描述符
  • poll/select:多路复用
  • mmap:内存映射文件
  • /proc 虚拟文件系统
相关推荐
秋风起,再归来~20 分钟前
【Linux庖丁解牛】— 线程控制!
linux·c++·算法
贾saisai23 分钟前
LINUX(三)文件I/O、对文件打开、读、写、偏移量
java·linux·数据库
沉在嵌入式的鱼24 分钟前
RK3588移植Openssl库
linux·rk3588·openssl
DIY机器人工房43 分钟前
完整的 SquareStudio 注册登录功能实现方案:已经烧录到开发板正常使用
linux·嵌入式硬件·嵌入式·diy机器人工房
挑战者6668881 小时前
MySQL 配置性能优化实操指南:分版本5.7和8.0适配方案
linux·运维·服务器·数据库·mysql·adb·性能优化
A蜂蜜罐头1 小时前
本地部署Dify、Docker重装
运维·docker·容器·dify
望获linux2 小时前
【实时Linux实战系列】实时任务与信号处理
linux·开发语言·前端·数据库·chrome·操作系统·嵌入式软件
IT成长日记2 小时前
【Docker基础】深入解析Docker-compose核心配置:Services服务配置详解
运维·docker·容器·服务配置·services
Tassel_YUE2 小时前
tcpdump 命令解析(随手记)
服务器·网络·tcpdump
后院那片海2 小时前
部署Zabbix企业级分布式监控
运维·架构·php