文件操作
文件操作级别
- 文件操作分为五个级别:
- 硬件级别
- fdisk
- mkfs
- fsck
- 碎片整理
- 操作系统内核中的文件系统函数
- 系统调用
- I/O库函数
- 用户命令
- sh脚本
- 硬件级别
文件I/O操作
- 双线上方的上半部分表示内核空间,下半部分表示进程的用户空间
- 该图显示了进程读/写文件流时的操作序列
低级别文件操作
分区
- 一个块存储设备,如硬盘、U盘、SD卡等,可以分为几个逻辑单元,称为分区
- fdisk是一个交互程序。它有一个显示所以命令的帮助菜单。它收集用户的输入,在内存中创建一个分区表,该分区表仅在用户输入w命令时才被写入磁盘映像的MBR。但是在内存中,它允许用户创建、检查和修改分区。
格式化分区
- 为了存储文件,必须先为特定的文件系统准备好分区,该操作习惯上称为格式化磁盘或磁盘分区。
挂载分区
- 用dd命令创建一个虚拟磁盘映像
- dd if=/dev/zero of=vdisk bs=1024 count=32768
- 在vdisk上运行fdisk来创建一个分区P1
- fdisk vdisk
- 使用以下扇区数在vdisk的分区1上创建一个循环设备
- losetup -o $(expr 2048 * 512) --sizelimit $(expr 65535 * 512) /dev/loop1 vdisk
使用系统调用进行文件操作
系统调用
- 系统调用(简称syscall)是一种允许进程进入Kmode以执行Umode不允许操作的机制
系统调用手册页
- man2子目录中列出了所以系统调用手册页
man 2 stat
man 2 open
man 2 read
使用系统调用进行文件操作
- 系统调用必须由程序发出,它们的用法就像普通函数调用一样。每个系统调用都是一个库函数,它汇集系统调用参数,并最终向操作系统内核发出一个系统调用
常用的系统调用
- stat: 获取文件状态信息
- int stat(char *filename, struct stat *buf)
int fstat(int filedes, dtruct stat *buf)
int lstat(char *filename, struct stat *buf)
- int stat(char *filename, struct stat *buf)
- open: 打开一个文件进行读、写、追加
- int open(char *file,int flags, int mode)
- close: 关闭打开的文件描述符
- int close(int fd)
- read:读取打开的文件描述符
- int read(int fd,char buf[ ],int count)
- write:写入打开的文件描述符
- int write(int fd, char buf[ ], int count)
链接文件
- 硬链接文件
- 命令
ln oldpath newpath - 创建从newpath到oldpath的硬链接。对应的系统调用
link(char *oldpath, char *newpath)
- 命令
- 软链接
- 命令
ln -s oldpath newpath - 创建从newpath到oldpath的软链接或符号链接。对应的系统调用
symlink(char *oldpath, char *newpath)
- 命令
stat系统调用
-
#include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> int main() { const char *file_path = "/path/to/your/file"; // 替换成您要查询的文件的路径 struct stat file_info; // 使用stat()函数获取文件信息 if (stat(file_path, &file_info) == 0) { printf("文件信息:\n"); printf("文件大小: %ld 字节\n", file_info.st_size); printf("文件权限: %o\n", file_info.st_mode & 0777); printf("文件拥有者的用户ID: %d\n", file_info.st_uid); printf("文件拥有者的组ID: %d\n", file_info.st_gid); printf("设备ID: %ld\n", file_info.st_dev); } else { perror("获取文件信息失败"); return EXIT_FAILURE; } return EXIT_SUCCESS; }
文件类型和权限
- 在stat结构体中,大多数字段都无需解释。只有st_mode字段需要进行说明
opendir-readdir函数
readlink函数
- Linux的open()系统调用遵循符号链接。因此,无法打开符号链接文件并读取其内容。要想读取符号链接文件的内容,我们必须使用readlink系统调用,即:
int readlink(char *pathname, char buf[],int bufsize);
open-close-lseek系统调用
- open:打开一个文件进行读、写、追加
- int open(char *file, int flags, int mode);
- close:关闭打开的文件描述符
- int close(int fd);
- read:读取打开的文件描述符
- int read(int fd, char buf[], int count);
- write:写入打开的文件描述符
- int write(int fd, char buf[], int count);
- lseek:将文件描述符的字节偏移量重新定位为偏移量
- int lseek(int fd, int offset, int whence);
- umask:设置文件创建掩码;文件权限为(mask& ~mask)
文件操作示例程序
苏格拉底挑战