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 虚拟文件系统
相关推荐
IvanCodes4 分钟前
十二、Linux Shell脚本:正则表达式
linux·运维·正则表达式
拾心211 小时前
【运维进阶】LAMPLNMP 最佳实践
运维
CodeDevMaster2 小时前
Linux中tmux入门使用指南:告别SSH断线烦恼,提升终端工作效率的神器
linux·运维·ssh
Brandon汐2 小时前
在Linux中部署tomcat
linux·运维·tomcat
sniper_fandc2 小时前
VirtualBox虚拟机网卡配置
linux·网络·虚拟机
白鸽梦游指南3 小时前
RHCE模拟测试
linux·运维·服务器
SRETALK3 小时前
夜莺开源监控,模板函数一览
运维·监控·自动化运维
不会吉他的肌肉男不是好的挨踢男3 小时前
Linux生成自签名 SSL 证书(适用于测试或内部使用)
linux·运维·ssl
飘忽不定的bug3 小时前
linux磁盘加密
linux·开源
herderl3 小时前
【无标题】命名管道(Named Pipe)是一种在操作系统中用于**进程间通信(IPC)** 的机制
java·linux·服务器·嵌入式硬件·php