文件系统
“裸奔”层次:不带操作系统编程
| 层级 | 说明 |
|---|---|
| APP | 应用层 |
| Hardware | 硬件层 |
特点:
- 简单粗暴:应用层直接操作硬件(寄存器、IO口等)。
缺点:
- 开发需理解原理图和硬件细节。
- 仅支持单任务运行,无法并发。
带操作系统的编程
| 层级 | 说明 |
|---|---|
| APP | 应用层 |
| OS | 操作系统 |
| Hardware | 硬件层 |
特点:
- 开发聚焦应用逻辑,无需关心硬件细节。
- 支持多任务并发运行。
缺点:
- API数量庞大。
- API功能可能不符合特定需求。
操作系统(OS)定义:
- 直接运行在“裸机”上的基础系统软件,所有应用软件依赖其支持。 常见操作系统:
- Windows(x86/xp/win8/win10/win11)
- Linux(Ubuntu/CentOS/RedHat/Kali)
- macOS
- iOS
- Android
- 鸿蒙
- Unix
Linux开发特点:
- 通过调用Linux提供的系统API接口操作硬件或使用系统服务。
Linux文件系统
核心理念:一切皆文件。所有操作通过文件接口实现。
文件系统组成
文件系统是存储、组织、管理和提供访问文件的一套方式、方法、协议及软件实现。
文件:
- 文件属性:由
inode(索引节点)管理,存储文件元数据(权限、大小等)。 - 文件内容:实际存储的数据。
文件操作过程
- 硬链接:通过文件名找到对应
inode。 - 内核数据结构:
struct inode:描述文件的物理信息(内核创建)。struct file:描述已打开文件的状态(如文件偏移量)。- 一个文件可被多个应用打开,每个打开操作对应独立的
struct file。
- 操作流程:plaintext
进程文件表项 → struct file → struct inode → 硬件inode → 文件内容
进程文件表项
每个进程维护一个文件指针数组(struct file* [])。
- 文件描述符(fd):数组下标,标识打开的文件。
open()返回 fd,后续操作通过 fd 访问文件。
系统IO函数:
open(),read(),write(),close()等由操作系统提供的文件操作接口。
Linux系统IO操作
打开文件:open()
函数原型:
c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// 版本1
int open(const char *pathname, int flags);
// 版本2(创建文件时)
int open(const char *pathname, int flags, mode_t mode);参数说明:
pathname:文件路径(含文件名和扩展名)。flags:打开方式标志位:O_RDONLY:只读O_WRONLY:只写O_RDWR:可读可写O_CREAT:文件不存在时创建(需配合mode参数)。
mode:文件权限(八进制数,如0777)。实际权限 =mode & ~umask。
返回值:
- 成功:文件描述符(
fd)。 - 失败:
-1。
读取文件:read()
函数原型:
c
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);参数说明:
fd:文件描述符(open()返回)。buf:存储读取数据的内存地址指针。count:需读取的字节数。
返回值:
- 成功:实际读取的字节数。
- 失败:
-1。
写入文件:write()
函数原型:
c
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);参数说明:
fd:文件描述符。buf:待写入数据的内存地址指针。count:需写入的字节数。
返回值:
- 成功:实际写入的字节数。
- 失败:
-1。
移动文件光标:lseek()
函数原型:
c
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);参数说明:
fd:文件描述符。offset:偏移字节数(正数向文件尾,负数向文件头)。whence:基准位置:SEEK_SET:文件开头SEEK_CUR:当前位置SEEK_END:文件末尾
返回值:
- 成功:实际偏移的字节数。
- 失败:
-1。
注意:偏移超出文件末尾形成“空洞”,写入时填充空洞。
关闭文件:close()
函数原型:
c
#include <unistd.h>
int close(int fd);参数说明:
fd:需关闭的文件描述符。
返回值:
- 成功:
0。 - 失败:
-1。
文件权限与 umask
权限计算规则
- 实际权限 = 指定权限
& ~umask。示例:plaintext指定权限:0777 umask:0022 实际权限:0777 & ~0022 = 0777 & 0755 = 0755
设置 umask
函数原型:
c
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);参数说明:
mask:新的权限掩码值。
返回值:
- 旧的
umask值。
注意:代码中的
umask设置不影响系统全局设定。
作业
实现文件拷贝功能:将文件A的内容完整复制到文件B(B为空文件)。
步骤:
- 用
open()打开源文件(A)和目标文件(B)。 - 循环调用
read()从A读取数据到缓冲区。 - 调用
write()将缓冲区数据写入B。 - 用
close()关闭两个文件。
总结:
- 系统IO:Linux通过文件描述符抽象文件操作。
- 核心函数:
open、read、write、lseek、close实现完整文件管理。 - 权限控制:
umask调节文件创建时的实际权限。
