基础IO———第一篇

在第一篇中我们需要掌握一下内容:
*复习C文件IO相关操作
*认识文件相关系统调用接口
*认识文件描述符,理解重定向
一、复习文件IO相关操作
回顾C库接口:
在这里插入图片描述
1.size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE *stream);
ptr:要写入的数据
size:每次写入的块长度
nmemb:总共写入给块个数
stream:文件流指针
返回值:正确返回写入的块数
2.int fseek(FILE *stream,long sffset,int whence);
stream:文件流指针
offset:偏移大小,有正负之分
whence:偏移位置
                SEEK_SET:文档起始位置
                SEEK_CUR:文档当前位置
                SEEK_END:文档末尾位置
3.int open(const char *pathname,int flags,mode_t mode);
paathname:文件路径名
flags:打开标志位
           O_PDONLY:只读
           O_WRONLY:只写
           O_RDWR:读写
           O_CREAT:文件存在则打开,不存在则创建
           O_EXCL:与O_CREAT同用,文件存在则报错返回
           O_TRUNC:打开文件同时清空原有内容
           O_APPEND:追加
mode:权限
返回值:文件描述符(非负整数)
4.ssize_t write(int fd,const void *buf,size_t count);
fd:文件描述符
buf:要写入的文件
count:要写入的数据长度
返回值:实际写入的数据长度(字节)失败:-1
二、系统调用接口
open、write、read、lseek、fileno、truncate
三、文件描述符(重要)
1.首先我们要知道文件描述符是什么?
文件描述符(是一个非负整数),是文件的操作句柄。
2.凭什么数字可以操作文件?
我们得知道文件描述符的原理:描述+组织
下面我们用一个比较形象的示意图来表示文件描述符的工作原理:
在这里插入图片描述
在进程中会打开稳夺文件,进程就需要对文件进行管理,他的管理方式就是:描述(struct file)+组织(数组);描述符就是这个文件描述结构体数组的下标,文件操作就是通过描述符(下标)找到对应的文件描述信息,进而对文件i女性操作。
3.文件系统调用和文件描述符的关系(系统调用和库函数之间的关系)
在这里插入图片描述
库函数是系统调用接口的一层封装,文件流指针中只有一个成员就是文件描述符;我们所说的printf缓冲区其实是FILE这个结构中定义的缓冲区。
用库函数打开一个文件其实会创建两个结构一个是内核空间中的struct file,另外一个是用户空间的struct FILE。
四、文件重定向
1.定义:实际上它就是改变数据的流向;本质就是改变文件描述符再文件描述结构体数组中对应的文件描述信息。说白了就是将下标对应的文件信息改变成另外一个文件的描述信息。
注意:改变的只是文件描述符数组中的下标,文件的内容并不会改变。
在这里插入图片描述
2.【笔试题】
(1)./a.out 1 > /dev/null 2 > &1
(2)./a.out 2 > &1 > /dev/null
以上两个式子中的重定向以后表示的意思功能有什么不同?
答:
首先我们得知道标准输出重定向1(>):它表示将原本要写入终端显示的数据写入到指定文件中,并且清空文件中原有的内容;
标准输出重定向1(>>):将原本要写入到终端显示器的数据追加到指定文件中。
对于(1),我们先画一个文件描述符的数组图来分析一下:
在这里插入图片描述
从上面的结果分析我们可以知道(1)的功能是:首先将./a.out这个文件从标准终端输出重定向到/dev/null文件,然后本来标准输出错误重定向到标准终端输出,但是由于它已经重定向到了/dev/null这个文件,所以标准输出错误也重定向到/dev/null这个文件;
对于(2),我们首先也通过画图来分析:
在这里插入图片描述
通过上图的分析,我们可以知道(2)中,首先是将./a.out这个文件通过从定向将标准错误输出重定向到标准终端输出,然后再将标准终端输出重定向到文件/dev/null中;需要注意的是这个文件错误信息依然会在标准终端输出中打印。
3.文件重定向的实现:dup/dup2
dup2(int oldfd, int newfd):将newfd指向oldfd所指向的文件。
eg:dup2(3,1):将1重定向到3,并且会关闭1所指文件。
五、文件系统的理解
目录结构与磁盘分区是独立的:
在这里插入图片描述
1.怎么将一个文件存到磁盘中:首先到data_bitmap中找到一个空闲的数据区域,,然后再去inode_bitmap中找到一个inode节点空闲的位置可以记录inode节点的位置,再然后根据这个位置将文件各种属性信息写进inode节点中,最后再根据刚开始获得的快区域的位置将文件数据写进磁盘的这个块区域。(我们之所以是这个顺序是因为首先我们需要确保有没有可以存放这个文件块位置,如果有了那么还有需要记录这个文件的相关信息需要一个inode节点,这个节点也得先确保是否有空缺位置,如果有再根据提示找到这个inode节点将文件各种属性信息写进去,最后将文件写进块区域;这些步骤都是按照顺序来的,如果有一个不符合那么就表明此时磁盘不可以存储文件)
2.读取一个文件的流程:
目录文件中存储的是文件目录项(文件名+inode节点号),我们读取一个文件就是通过文件名找到inode节点号,然后通过inode节点号在inode区域中找到对应的inode节点,再通过inode节点中记录的数据块编号找到文件数据。
在这里插入图片描述
3.【笔试题】软链接和硬链接文件有什么区别?
(1)首先我们认识什么是软链接和硬链接:
*软链接:类似于快捷方式的文件,指向了另外一个文件,一个单独的文件。并且文件中记录的是所指向文件位置。操作软链接文件就是相当于操作所指向的源文件。
*创建软链接:ln -s 文件名1 文件名2 ==》文件名2 -》文件名1
*硬链接:硬链接文件就相当于是文件的一个别名,意味着多个文件指向了同一个inode节点。
*创建硬链接:ln 文件名1 文件名2
(2)系统删除文件原理
每个文件都有一个链接,链接数就表示inode节点有几个目录项,我们删除一个文件,链接数就减1,实际删除的是目录项;只有当目录项具有的链接数为0的时候才会将文件信息全部删除。
(3)它们两个的区别
1)软链接是单独的文件而硬链接是文件的一个目录项;所以若删除源文件,软链接就无法操作了,但是硬链接不会收到影响。
2)软链接可以跨分区,但是硬链接不可以,因为硬链接的inode节点会重复
3)软链接为目录创建,但是硬链接不可以。
(4)【acm】 下面解释一下文件的三个时间:
Access 最后访问时间
Modify 文件内容最后修改时间
Change 属性最后修改时间
4.动态库/静态库
(1)概念
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中;程序运行的时候将不再需要静态库。
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
(2)创建
[root@localhost linux]# ls
add.c add.h main.c sub.c sub.h
[root@localhost linux]# gcc -c add.c -o add.o [root@localhost linux]# gcc -c sub.c -o sub.o
1)生成静态库:
[root@localhost linux]# ar -rc libmymath.a add.o sub.o ar是gnu归档工具,rc表示(replace and create)
查看静态库中的目录列表
[root@localhost linux]# ar -tv libmymath.a
2)生成动态库:
shared: 表示生成共享库格式
fPIC:产生位置无关码(position independent code)
库名规则:libxxx.so
使用动态库
编译选项
l:链接动态库,只要库名即可(去掉lib以及版本号)
L:链接库所在的路径.
示例: gcc main.o -o main –L. -lhello
运行动态库
1、拷贝.so文件到系统共享库路径下, 一般指/usr/lib
2、更改 LD_LIBRARY_PATH

猜你喜欢

转载自blog.csdn.net/ZhuiZhuDream5/article/details/88068340