基础IO
w:写入,每次写入都是重新写入,意味着之前的文件内容。会被清空。
a:append,追加,本质:也是写入,不清空原始文件内容,在文件最后进行写入,数据增多的过程。
任何C程序,都默认会打开三个“文件”,分别叫做标准输入(stdin),标准输出(stdout),标准错误(stderr)。
所有的外设硬件,本质对应的核心操作无外乎是read和write。
1.不同的硬件,对应的读写方式肯定是不一样的。
C程序会默认打开stdin,stdout,stderr。
file descriptor:文件描述符
FILE *:文件指针
所有的文件,如果要被使用,首先必须被打开。一个进程可以打开多个文件。系统内被打开的文件,一定是有多。这些被打开的文件,要被OS管理起来。
结论:用户层看到的fd,本质是系统中维护进程和文件对应关系的数组的下标!
所谓的默认打开文件,标准输入,标准输出,标准错误,其实是有底层系统支持的。默认一个进程在运行的时候,就打开了0,1,2(文件描述符)。
系统中,分配文件描述符的规则:最小的,没有被使用的,进行分配。
struct FILE内部包含:
1.底层对应的文件描述符下标
2.应用层,C语言提供的缓冲区数据
显示器上是行缓冲刷新策略,文件里面是全缓冲刷新策略。
文件描述符就是从0开始的小整数。当我们打开文件时。操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files,指向一张表files_struct,该表最重要的部分就是包含一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件。
inode:
1.基本上,一个文件一个inode(包括目录)。
2.inode是一个文件的所有的属性集合(也是数据,也要占据空间)。
3.真正标识文件的不是文件名,而是文件的inode编号。
4.inode是可以和特定的数据块产生关联的。
5.Linux下属性和内容是分离的,属性inode保存,内容data block保存。
软链接就是一个普通的正常文件,有自己独立的inode编号!
硬链接没有自己独立的inode!(相当于文件的别名)
动、静态链接
Linux中,默认情况下,形成的可执行程序,是动态链接的。
将库中的我的可执行程序中使用的二进制代码,拷贝进我的可执行程序中,叫做静态链接。
动态库 libc.so
静态库 libc.a
命名:取消前缀lib,去掉.之后的内容,剩下的就是库的名字。
动态链接的特点:体积小,节省资源(磁盘,内存),一旦库丢失,bin不可执行。
静态链接的特点:体积大,浪费资源(磁盘,内存),不依赖库,库丢失,不影响。
理解动静态库:
1.如何打包静态库?
我们让别人能使用我们的库,前提是别人需要首先知道你的库(不想暴露自身的源代码),能给我提供什么方法(头文件)!
2.如何使用静态库?
示例:gcc main.c -o main -I ./lib -L ./lib -l mymath
-I ./lib
-I:告诉gcc除了默认路径以及当前路径,在指定路径下也找一下头文件。
-L ./lib
-L:告诉gcc除了默认路径以及当前路径,在指定路径下也找一下库文件。
-l mymath
-l(L的小写)库名称:具体你要链接哪一个库。
为什么C语言在编译的时候,从来没有明显的使用过-L、-I、-l等选项呢?
1.库文件和头文件,在默认路径下gcc能找到。
2.gcc编译C代码,默认就应该链接libc。
如果我们也不想使用这些选项内容?
头文件、库文件分别拷贝到默认路径下,这叫做库的安装!
1.如何打包动态库?
示例:[root@localhost linux]# gcc -fPIC -c sub.c add.c [root@localhost linux]# gcc -shared -o libmymath.so
2.如何使用动态库?