25.12.27 理解文件本质+文件系统调用接口+fd+重定向

文章目录

  • [1. 理解文件](#1. 理解文件)
  • [2. 系统调用接口](#2. 系统调用接口)
  • [3. 理解fd](#3. 理解fd)

1. 理解文件

文件 = 文件属性 + 文件内容

文件系统包括了加载到内存中的文件和保存在磁盘中的文件两大类

重点谈加载到内存中的文件:

根据冯诺依曼体系->文件从磁盘中加载到内存缓冲区中,等待CPU执行,这个过程由进程进行文件操作

而在代码中的体现:

研究打开的文件,本质是研究进程和文件之间的关系

2. 系统调用接口

cpp 复制代码
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>

int open(const char* pathname, int flags, mode_t mode);
  • pathname:文件路径名
  • flags:标志位,位图->32个bit位,有几个常见的宏
    • O_RDONLY:只读
    • O_WRONLY:只写
    • O_RWDWR:读写
    • O_CREAT:新建
    • O_APPEND:追加
    • O_TRUNC:清空
  • mode:设置文件权限,设置的权限要&(~umask)
cpp 复制代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(){
  open("log.txt",O_TRUNC | O_RDWR, 666); // 清空+读写
  return 0;
}
bash 复制代码
[vect@VM-0-11-centos file]$ cat log.txt
hghhssladj
sajldjas
asld
[vect@VM-0-11-centos file]$ gcc open.c
[vect@VM-0-11-centos file]$ ./a.out 
[vect@VM-0-11-centos file]$ cat log.txt 
[vect@VM-0-11-centos file]$ 

写操作:

读操作:

关闭操作:

C的文件操作函数都是基于这四个系统调用接口封装的

3. 理解fd

文件描述符->本质是数组索引

文件加载到内存中需要管理->需要管理文件属性和文件内容->怎么管理?->先描述,再组织!

fd分配原则: 进程启动默认打开三个文件流:stdin stdout stderr 索引依次为1 2 3,新打开的文件按照未分配最小的索引开始,依次按照文件打开顺序递增分配

这里涉及到重定向:

使用dup2完成重定向

cpp 复制代码
#include <unistd.h>
int dup2(int oldfd, int newfd);

这句话的意思是newfdoldfd的拷贝,所以重定向到newfd

cpp 复制代码
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(){
  int fd1 = open("log1.txt",O_CREAT | O_RDWR,0666);
  int fd2 = open("log2.txt",O_RDWR | O_CREAT,0666);
  int fd3 = open("log3.txt",O_RDWR | O_CREAT,0666);

  dup2(fd1,1);
  printf("%d\n",fd1);
  printf("%d\n",fd2);
  printf("%d\n",fd3);

}
bash 复制代码
[vect@VM-0-11-centos file]$ gcc dup2.c 
[vect@VM-0-11-centos file]$ ls
a.out  dup2.c  log.txt  open.c  proc.c
[vect@VM-0-11-centos file]$ ./a.out 
[vect@VM-0-11-centos file]$ ls
a.out  dup2.c  log1.txt  log2.txt  log3.txt  log.txt  open.c  proc.c
[vect@VM-0-11-centos file]$ cat log1.txt 
3
4
5

本来应该输出到显示器,但是重定向输出到文件里了

相关推荐
顺风尿一寸12 分钟前
Java Socket 内核之旅:从 SocketChannel.read() 到 tcp_recvmsg 与 epoll 的完整调用链路
linux
XIAOHEZIcode6 小时前
Ubuntu 终端美化全栈指南:Bash 到 Kitty 踩坑实录
linux·ubuntu·命令行
唐青枫8 小时前
别再只会用 cron:Linux systemd Timer 定时任务实战详解
linux
AlfredZhao2 天前
生产环境里,为什么不建议把普通端口直接暴露到公网?
linux·https·443·80
戴为沐3 天前
Linux内存扩容指南
linux
zylyehuo4 天前
Linux 彻底且安全地删除文件
linux
用户805533698034 天前
主线 U-Boot 上 RK3506:和闭源 rkbin 拔河的三个隐性契约
linux·嵌入式
用户034095297914 天前
linux fcitx 5 雾凇拼音 设置在中文输入法下仍然输入英文标点
linux
Web3探索者6 天前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
zylyehuo6 天前
Linux系统中网线与USB网络共享冲突
linux