动静态库和文件系统

1.文件简介

       文件=内容+属性,所有文件操作分为内容和属性操作;并且内容和属性都是数据,所以存储文件必须两者都要存储。文件被打开前是普通的磁盘文件,被进程打开后被加载到内存中。

2.系统文件和库函数文件I/O接口

fopen ,fclose ,fread ,fwrite 都是C标准库当中的函数,我们称之为库函数。

open,close,read,write,lseek 都属于系统提供的接口,称之为系统调用接口。简单来说,库函数都是对系统调用接口的封装,方便二次开发。

其中,系统调用接口的参数与库函数基本相同,只是其中的打开方式和返回值不同。

打开方式:O_RDONLY: 只读打开。

                  O_WRONLY: 只写打开。

                  O_RDWR : 读,写打开 这三个常量,必须指定一个且只能指定一个。

                 O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访权限                       O_APPEND: 追加写。

返回值: 成功:新打开的文件描述符 ;失败:-1。

3.文件描述符fd
磁盘中的文件被打开始先在内存中开好一个struct file对象用指针连接。在进程的pcb中有一个struct file_struct 指针对象,对象中包含一个struct file类型的数组,其中该数组0为stdin(标准输入,键盘),1为stdout(标准输出,显示器),工为stderr(标准错误,显示器)会默认被打开。 fd是一个连续的小整数,本质是数组的下标。系统访问文件只认fd。

文件描述符的分配规则:在数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。

4.重定向

本质上是上层的fd不变,下层fd指向的内容改变。

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main() {
  int fd = open("./log", O_CREAT | O_RDWR);
  if (fd < 0) {
    perror("open");
    return 1;
  }
  close(1);
  dup2(fd, 1);
  for (;;) {
    char buf[1024] = {0};
    ssize_t read_size = read(0, buf, sizeof(buf) - 1);
    if (read_size < 0) {
      perror("read");
      break;
    }
    printf("%s", buf);
    fflush(stdout);
  }
  return 0;
 }

5.缓冲区

缓冲区的主要作用是提高使用者的效率,因为其可以使数据积累到一定数量在统一发送。

缓冲区因为其能够暂时存储数据,所以有三种刷新方法:无缓冲;行缓冲(一般用于显示器文件);全缓冲(一般用于磁盘文件)。但是当进程退出时和使用fflush函数要强制刷新缓冲区。


#include <stdio.h>
#include <string.h>
 
int main()
 {
    const char *msg0="hello printf\n";
    const char *msg1="hello fwrite\n";
    const char *msg2="hello write\n";
 
    printf("%s", msg0);
    fwrite(msg1, strlen(msg0), 1, stdout);
    write(1, msg2, strlen(msg2));
 
    fork();
 
    return 0;
}

注意:printf fwrite 库函数会自带缓冲区,而 write 系统调用没有带缓冲区。另外,我们这里所说的缓冲区, 都是用户级缓冲区。其实为了提升整机性能,OS也会提供相关内核级缓冲区printf fwrite 是库函数, 调用的“封装”,但是 write 没有缓冲区,而 C,所以由C标准库提供。

6.文件系统

Linux ext2文件系统,上图为磁盘文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,硬盘分区被划分为一个个的block。一个block的大小是由格式化的时候确定的,并且不可以更改。

磁盘格式化时会被分为三个存储区域:超级块,索引节点,数据块区。

索引节点:inode Table;i节点表,存放文件属性,128字节;inode Bitmap:使用位图表示一个inode是否空闲。

数据块区:Date blocks:存放文件内容,每一个4kb大小;Block Bitmap:记录Date blocks中哪个数据块是否被占用。

超级块:Super Block:存放文件系统本身的结构信息,如block和inode总量,未被使用的block和inode数,一个block和inode大小等。即用来记录和管理整个文件系统,若被破坏了,则整个文件系统结构就被破坏了。

7.软硬链接

硬链接:不是一个独立的文件,是在指定目录下文件名和inode的映射关系。真正找到磁盘上文件的并不是文件名,而是inode。 其实在linux中可以让多个文件名对应于同一个 inode。在删除文件时干了两件事情:1.在目录中将对应的记录删除,2.将硬连接数-1,如果为0,则将对应的磁盘释放。

软链接:是一个独立的文件,内容是指向目标文件的路径,类似于window的快捷方式。

总的来说,硬链接是通过inode引用另外一个文件,软链接是通过名字引用另外一个文件。

8.动静态库

静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。

动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文 件的整个机器码。

在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个 过程称为动态链接(dynamic linking)。

动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚 拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sakura&NANA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值