Linux——基础IO&软硬链接

目录

基础IO

FILE*

缓冲区

用户文件缓冲区

用户文件缓冲区的刷新策略

两种情况

文件内核缓冲区

文件描述符

文件打开的全过程

链接

软链接

硬链接

取消链接

路径解析死循环问题


只有认知的突破 💫才能带来真正的成长 💫编程技术的学习 💫没有捷径 💫一起加油💫

🍁感谢各位的观看 🍁欢迎大家留言 🍁咱们一起加油 🍁努力成为更好的自己🍁

基础IO

在Linux中,"一切皆文件"。所以IO操作就是进程和文件之间进行数据的交互。

FILE*

在C语言中,文件指针FILE*对应的是FILE结构体,其结构如下所示。

cpp 复制代码
typedef struct _IO_FILE {
    int _flags;          // 文件状态标志(如只读、可写、错误、EOF等)
    char* _IO_read_ptr;  // 缓冲区当前读取位置
    char* _IO_read_end;  // 缓冲区读取结束位置
    char* _IO_read_base; // 缓冲区起始地址(读缓冲区)
    char* _IO_write_base;// 缓冲区起始地址(写缓冲区)
    char* _IO_write_ptr; // 缓冲区当前写入位置
    char* _IO_write_end; // 缓冲区写入结束位置
    char* _IO_buf_base;  // 缓冲区基地址(若使用自定义缓冲区)
    char* _IO_buf_end;   // 缓冲区结束地址
    struct _IO_FILE* _chain; // 链表指针(用于关联多个打开的文件)
    int _fileno;         // 底层文件描述符(Linux 中文件的唯一标识,如 0=stdin、1=stdout、2=stderr)
    int _err;            // 错误码(记录文件操作错误)
    int _eof;            // EOF 标志(非0表示已到达文件末尾)
    // 其他成员:缓冲区大小、编码格式、锁机制等...
} FILE;

在这个结构体中,有2个属性重要一些,读写缓冲区和文件描述符。

缓冲区

缓冲区------文件内核缓冲区和用户文件缓冲区

用户文件缓冲区

用户文件缓冲区存在于C标准库中------存在于FILE中。如下图所示。

用户文件缓冲区的刷新策略
  • 无策略,直接刷新。

  • 行刷新,遇到'\n'(适用于显示器)。

  • 满刷新。

两种情况
  • 进程退出,直接刷新。

  • fflush强制刷新。

文件内核缓冲区

文件被打开后,OS会先创建这个文件的struct file结构体,然后在内存中再为这个文件创建三个空间,来存储这个文件的相关信息。文件属性,读写方法和文件内核缓冲区。如下图所示。

文件描述符

  • C库中的文件操作函数,都是对系统函数的封装。在上层C库中,我们打开一个文件就会返回一个FILE*的指针。其实,底层的函数会返回一个int型的数值,然后把这个数值返回给上层,上层再对这个数值进行封装------填充FILE的文件描述符属性,最后返回FILE*。

  • 文件描述符就是一个普通的整形,它就是数组(文件描述符表)的下标。

  • 底层返回整形,上层再对它进行封装,然后上层便可得到FILE*。

  • 返回未被使用的最小的数组下标。

fd------>FILE*的过程代码如下所示:

cpp 复制代码
struct IO_FILE 
{ 
int flag; // 刷新⽅式 
int fileno; // ⽂件描述符 
char outbuffer[SIZE]; 
int cap; 
int size; 
// TODO 
};

typedef struct IO_FILE mFILE;

mFILE *mfopen(const char *filename, const char *mode) 
{ 
    //。。。。。 
    fd = open(filename, O_RDONLY);
    mFILE *mf = (mFILE*)malloc(sizeof(mFILE)); 
    if(!mf) 
    { 
        close(fd); 
        return NULL; 
    } 
    mf->fileno = fd; 
    //mf->flag = FLUSH_LINE; 
    mf->size = 0; 
    mf->cap = SIZE; 
    return mf; 
}

文件打开的全过程

如下图所示。

一个文件被打开,有两个人要知道,一个是OS,另一个就是进程本身。进程是自己的文件描述符表来知晓,而OS则进行双链表来管理。

链接

软链接

ln -s src dst

cpp 复制代码
ln -s code.c code_soft


ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ ls -l
total 4
drwxr-xr-x 2 ubuntu ubuntu 4096 Jan 12 11:09 A
-rw-r--r-- 1 ubuntu ubuntu    0 Jan 12 11:09 code.c
ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ ln -s code.c code_soft
ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ ll
total 12
drwxr-xr-x 3 ubuntu ubuntu 4096 Jan 12 11:09 ./
drwxr-xr-x 6 ubuntu ubuntu 4096 Jan 12 11:08 ../
drwxr-xr-x 2 ubuntu ubuntu 4096 Jan 12 11:09 A/
-rw-r--r-- 1 ubuntu ubuntu    0 Jan 12 11:09 code.c
lrwxrwxrwx 1 ubuntu ubuntu    6 Jan 12 11:09 code_soft -> code.c
ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ vim code.c
ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ cat code_soft
jjjjjj
  • 文件内容里面存储的是被链接文件的路经。

  • 相当于软件的快捷方式。

硬链接

ln src dst

cpp 复制代码
 ln code.c code_hard


ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ ln code.c code_hard
ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ ll
total 20
drwxr-xr-x 3 ubuntu ubuntu 4096 Jan 12 11:15 ./
drwxr-xr-x 6 ubuntu ubuntu 4096 Jan 12 11:08 ../
drwxr-xr-x 2 ubuntu ubuntu 4096 Jan 12 11:09 A/
-rw-r--r-- 2 ubuntu ubuntu    7 Jan 12 11:10 code.c
-rw-r--r-- 2 ubuntu ubuntu    7 Jan 12 11:10 code_hard
lrwxrwxrwx 1 ubuntu ubuntu    6 Jan 12 11:09 code_soft -> code.c
  • 硬链接就是给被链接文件取"别名"==引用。

  • 硬链接不能链接目录,否则就会出现路径解析死循环。

  • 被硬链接指向的时候,被硬链接的文件,就会计数一下。

取消链接

对于软硬链接取消链接,指令:unlink 链接

cpp 复制代码
 unlink code_soft


ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ ll
total 20
drwxr-xr-x 3 ubuntu ubuntu 4096 Jan 12 11:15 ./
drwxr-xr-x 6 ubuntu ubuntu 4096 Jan 12 11:08 ../
drwxr-xr-x 2 ubuntu ubuntu 4096 Jan 12 11:09 A/
-rw-r--r-- 2 ubuntu ubuntu    7 Jan 12 11:10 code.c
-rw-r--r-- 2 ubuntu ubuntu    7 Jan 12 11:10 code_hard
lrwxrwxrwx 1 ubuntu ubuntu    6 Jan 12 11:09 code_soft -> code.c
ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ unlink code_soft
ubuntu@VM-4-17-ubuntu:~/review-linux/2026_1_12$ ll
total 20
drwxr-xr-x 3 ubuntu ubuntu 4096 Jan 12 11:21 ./
drwxr-xr-x 6 ubuntu ubuntu 4096 Jan 12 11:08 ../
drwxr-xr-x 2 ubuntu ubuntu 4096 Jan 12 11:09 A/
-rw-r--r-- 2 ubuntu ubuntu    7 Jan 12 11:10 code.c
-rw-r--r-- 2 ubuntu ubuntu    7 Jan 12 11:10 code_hard

路径解析死循环问题

硬链接不能链接目录,只能链接普通文件,而软连接可以链接目录/普通文件。

原因:

路径解析不是看文件名解析的,而是看文件的inode进行路径解析的。举个例子,当A目录里面--->有个子目录B,B目录里面有个硬链接C,C链接到B目录。当执行cd A/B/C,就会出现路径回环问题,死循环。如下图所示。

而软链接就不会出现这种情况,因为软连接是个独立的文件,有自己的inode,假设C软链接到B,它里面存的是被链接文件的路径,所以,当解析的C时,会继续解析C里面的路径,就会解析到B文件,就会停止了。

相关推荐
2401_858936883 小时前
【Linux C 编程】标准 IO 详解与实战:从基础接口到文件操作实战
linux·c语言
Roc.Chang3 小时前
Ubuntu 下 VLC 无法启动(Segmentation fault)终极解决方案
linux·ubuntu·vlc·媒体播放
松涛和鸣4 小时前
72、IMX6ULL驱动实战:设备树(DTS/DTB)+ GPIO子系统+Platform总线
linux·服务器·arm开发·数据库·单片机
Anesthesia丶4 小时前
Ubuntu20.04 升级 Ubuntu24.04 LTS
ubuntu
简单中的复杂4 小时前
【避坑指南】RK3576 Linux SDK 编译:解决 Buildroot 卡死在 host-gcc-final 的终极方案
linux·嵌入式硬件
wVelpro5 小时前
如何在Pycharm 2025.3 版本实现虚拟环境“Make available to all projects”
linux·ide·pycharm
程序员老舅5 小时前
C++高并发精髓:无锁队列深度解析
linux·c++·内存管理·c/c++·原子操作·无锁队列
雨中风华5 小时前
Linux, macOS系统实现远程目录访问(等同于windows平台xFsRedir软件的目录重定向)
linux·windows·macos
爱吃生蚝的于勒6 小时前
【Linux】进程信号之捕捉(三)
linux·运维·服务器·c语言·数据结构·c++·学习