目录
C文件接口
1.fopen
2.fwrite
?3.fread
4.fseek
?5.代码验证
?系统调用文件接口
1.open
2.write
3.read
4.lseek
5.代码验证
?文件描述符
文件描述符的值&含义
文件描述符与文件流指针的联系
重定向
动态库与静态库
静态库
动态库
C文件接口
1.fopen
作用:打开文件

mode打开文件的方式:
'r' 只读方式打开,将文件指针指向文件头,如果文件不存在,则返回空。 'r+' 读写方式打开,将文件指针指向文件头,如果文件不存在,则返回空。 'w' 写入方式打开,将文件指针指向文件头并将文件内容清空。如果文件不存在则创建。 'w+' 读写方式打开,将文件指针指向文件头并将文件内容清空。如果文件不存在则创建。 'a' 写入方式打开,将文件指针指向文件末尾。如果文件不存在则创建。 'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则创建。
2.fwrite
作用:往文件中写
3.fread
作用:从文件中读

4.fseek
作用:移动文件流指针的位置

?5.代码验证
#include <stdio.h>
2 #include <string.h>
3 int main(){
4 FILE* fp=fopen("bite","w+");
5 if(fp==NULL){
6 perror("fopen");
7 }
8 const char* ptr="linux so easy";
9 fwrite(ptr,1,strlen(ptr),fp);//将ptr中的内容写入文件bite中
10 fseek(fp,0,SEEK_SET);//将文件流指针偏移到文件的头
11 char str[1023]={0};
12 fread(str,1,sizeof(str)-1,fp);//将文件中的内容读到str数组中
13 printf("%s\n",str);//打印出来
14 fclose(fp);
15 return 0;
16 }
运行结果正确:

?系统调用文件接口
1.open
作用:打开文件

2.write
作用:往文件中写

3.read
作用:从文件中读

4.lseek

5.代码验证
1 #include <stdio.h>
2 #include <fcntl.h>
3 #include <string.h>
4 #include <unistd.h>
5 int main(){
6 int fd=open("bite",O_RDWR|O_CREAT,0664);//打开文件,若不存在则创建
7 if(fd<0){
8 perror("open");
9 }
10 const char* str="i like linux";
11 write(fd,str,strlen(str));//往文件中写
12 lseek(fd,0,SEEK_SET);//为下一次读做准备
13 char arr[1023]={0};
14 read(fd,arr,sizeof(arr)-1);//从文件中读
15 printf("%s\n",arr);
16 close(fd);
17 return 0;
18 }
?运行结果正确:

?文件描述符
文件描述符的值&含义
Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0, 标准输出1, 标准错误2。0,1,2对应的物理设备一般是:键盘,显示器,显示器
?。
如下代码:
?我们发现,拿到的文件描述符是3,这是一个正数,那么这个小正整数是什么意思呢?可以通过以下命令进入到指定文件夹查看文件描述符信息:
其中的软连接文件的名字,正好对应文件描述符的值。那么站在操作系统内核的角度上,又如何理解呢?请看下面这张图:
?当我们打开文件时,操作系统在内存中要创建相应的数据结构来 描述目标文件。于是就有了fifile结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进 程和文件关联起来。每个进程都有一个指针*fifiles, 指向一张表fifiles_struct,该表最重要的部分就是包涵一个指针数 组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。以,只要拿着文件 描述符,就可以找到对应的文件。
文件描述符与文件流指针的联系
文件流指针指向的结构体中保存了文件描述符,直接来看Linux的源代码(有省略):

那么到底是不是这样呢?来一段代码验证一下:
?运行结果正确。
重定向
重定向接口:

?作用:将newfd的值重定向为oldfd
?为什么会打印到屏幕上呢?
前面讲过文件描述符其实是一个结构体指针数组的下标,那么重定向就是改变了其中指针的指向(相当于一个指针变量拷贝了另一个指针变量的值),使本来指向文件1.txt对应的结构体的指针指向了标准输出,所以就打印到了屏幕上。如下图所示:

动态库与静态库
静态库

如下代码,将两个.o文件打包为静态库文件:
?这时候,只要有了静态库文件和头文件就可以正常使用了,如下,先创建一个.c文件,包含头文件后调用一下静态库中的函数:
??此时有报错,那么怎么解决这个问题呢?我们来写一个makefile,来解决这个问题:
?这样代码就可以正常执行了, 注意:程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。此时生成的可执行程序比较大。
动态库

我们此时还是使用静态库的那些.c文件,依照以上命令先生成一个动态库:

然后再来使用:
?此时我们make一下,看是否可以生成可执行文件:
?此时并没有运行成功,为什么呢?使用ldd命令查看一下可执行程序依赖的库:

那么怎样解决这个问题?其实只需要进入~/中将.bashrc文件中的环境变量LD_LIBRARY_PATH 加上当前动态库的路径就可以了,如下:
?此时就可以运行成功了。如果不想配置环境变量,还有两种方法可以使可执行程序链接到动态库:
1.将动态库放到可执行程序的路径下(不推荐)
2.将动态库放到系统库的路径下 :/lib64(不推荐)
|