目录
open
系统调用 和 库函数
重定向
文件管理、理解文件系统
静态库 动态库怎么打包
文件 = 内容 + 属性
FILE*, c语言,软件
如何理解硬件和软件的关系
stdin,标准输入,键盘
stdout,标准输出,显示器
stderr,标准错误,显示器
stdin & stdout & stderr,c语言默认打开三个输出流,标准输入流,标准输出流和标准错误。
Linux之下一切皆文件。
为什么提供三个接口?实现人与计算机的交互(通过语言)。
1.如何输入输出
stdin & stdout & stderr,c语言默认打开三个输出流,标准输入流,标准输出流和标准错误。
系统文件输入输出接口
open
open,有两种使用方式
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);其中pathname: 要打开或创建的目标文件
flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。
参数:
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR : 读,写打开
这三个常量,必须指定一个且只能指定一个
O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
O_APPEND: 追加写返回值:
成功:新打开的文件描述符
失败:-1那如何理解mode_t呢?
和使用权限有关。
const char *str = "hello world\n";
write(fd, str, strlern(str));
close(fd);
系统调用 和 库函数
我们要回顾一下系统调用 和 库函数的概念,知道系统调用是系统提供的接口,而库函数呢?
是为了用户更好的使用对系统调用的二次封装。
其中,fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。
而, open close read write lseek 都属于系统提供的接口,称之为系统调用接口。可以认为f系列函数是对接口的二次封装。
3,4,5,6 文件描述符fd(files descration),在os层面就是一个整数,从0到n,
0:标准输入
1:标准输出
2:标准错误
本质是数组下标
os要管理文件,结构体,多个文件多个结构体,链表组织
struct file{
//文件的属性信息
//文件的缓存和存储位置
}
进程是task_struct,进程访问文件,进程对文件 1:n
struct file*fd_array [结构体指针数组],pcb有指针fs指向其中。(struct file_struct中的)
什么是文件描述符
本质是数组下标,默认从小的分配,默认从3开始
通过结构体和函数指针实现面向对象
重定向
重定向:本来应该输出到显示器上的内容,输出到了文件当中,其中,fd=1。这种现象叫做输出
重定向。常见的重定向有:>, >>, <我们来看这一代码,我们会发现printf和fprinf打印了两次。
int main() { int fd = open("log.txt",O_CREAT | O_APPEND | O_WEONLY, 0644); if(fd < 0){ perror("open error"); return 1; } const char *str = "hello world: write\n"; const char *str1 = "hello world: print\n"; const char *str2 = "hello world: fprint\n"; write(1,str,strlen(str)); printf("%s",str1); fprintf(stout,"%s",str2); fork(); fflush(stdout); }
输出地一般有两种,
显示器,行缓冲
和文件,全缓冲
缓冲区,本质是一块内存
重定向,目的地发生变化,收缓冲影响。库函数受影响,缓冲区在库函数提供的。
用户级缓冲区,c标准库提供。(语言给我们提供的缓冲区)
先关闭1的重定向,
不关闭用dup,有dup和dup2,我们在这里学习dup2。
dup2(oldfd,newfd),内容的拷贝
dup2(fd,1)
close(fd)
数组内容的拷贝,内容的改变。
文件管理、理解文件系统
文件 = 内容 + 属性
一个文件
(1)inode{
属性集合
}
(n数据块)block{ 4kb为单位保存的
内容
}
file system{
基本情况
空间一共多大
已经被使用&&没有被使用
inode
block
group(高度概括)
方法
}
理解硬盘,里边是光盘(两面都是光的)6磁头,机械臂杆
盘面,柱面,扇区
硬盘想象成大数组,将对硬盘进行管理的问题转化为对数组进行管理的问题。
硬盘太大了,划分空间,(用文件系统)便于管理。(分区)
inode文件的属性 (个数是确定的)
Data block 数据
文件:inode: block = 1:1:n
inode id ,标识一个inode,是唯一的
目录是文件,有inode和block
怎么分配inode id
由i位图决定,多少id就是多少0 ,00000.......00000,比如第五个给了,就是00001......000。
同理b位图
想象为数组
通过位图知道inode和block的使用情况。
删除把1变为0.删除成本低
目录也是文件 = inode + 数据块(文件名 + inode映射关系)
硬链接
不是单独文件。和指向的文件共享一个inode。
是什么呢?
文件名和映射关系
软链接ln -s(本质上就相当于一个快捷方式)
是不是独立文件,是,有独立inode
stat 更多文件信息
静态库 动态库怎么打包
静态库.a 静态链接,将对应的代码拷贝进bin,体积比较大,bin可移植性强
链接的时候纳入进来
动态库 .so 动态库体积小,依赖库 运行的时候才加载
libc.so.6 根据命名规则,去掉lib和第一个点后边,就是库的名字,所以是c库。
使用需要提供
一批头文件:有什么方法可以使用,接口参数是什么意思
一个,多个库文件:具体的实现,供我们动静态链接
链接的本质:将你代码生成的.o文件进行打包
ar -rc libmypath.a myadd.o mysub.o 这一步是将myadd.o mysub.o打包成libmypath.a(打包库文件)
最后可打包成如图文件进行传输