标题
- 01.C语言的IO
1.c语言的IO函数
2.试用一下就知道
//写文件
int main()
{
//0.打开一个文件
FILE* file1 = fopen("./1.txt","w");
//1.向文件写数据
const char* str= "hello,world\n";
fwrite(str,strlen(str),1,file1);
//3.用fseek调整文件指针的位置
fseek(file1,0,SEEK_END);
//4.计算文件的大小
std::cout<<ftell(file1)<<std::endl;
//5.关闭文件描述符
fclose(file1);
return 0;
}
//程序执行结果
[skin@bogon Git]$ ./a.out
12
[skin@bogon Git]$ cat 1.txt
hello,world
//读文件
int main()
{
//0.打开文件
FILE* file = fopen("./1.txt","r");
//1.读取文件
const char* s = "hello,world\n";
char str[1024] = {0};
while(1)
{
ssize_t read_size=fread(str,1,strlen(s),file);
if(read_size>0)
{
//2.打印到标准输出上
std::cout<<str<<std::endl;
}
if(feof(file))
break;
}
//3.关闭文件描述符
fclose(file);
return 0;
}
//程序执行结果
[skin@bogon Git]$ ./a.out
hello,world
- 02.系统IO函数
1.看下这个系统的接口
2.感觉这个东西就是要用,所以就来使用下
//写文件
int main()
{
umask(0);
//0.打开文件,获取文件描述符(会面介绍)
int fd = open("./1.txt",O_RDWR | O_CREAT ,0644);
//1.读取标准输出,写入文件
char buf[1024]={0};
ssize_t read_size= read(0,buf,sizeof(buf)-1);
if(read_size<0)
{
perror("read");
return -1;
}
ssize_t wirte_size= write(fd,buf,strlen(buf));
if(wirte_size<0)
{
perror("write");
return -1;
}
return 0;
}
//程序执行结果
[skin@bogon Git]$ ./a.out
haha
[skin@bogon Git]$ cat 1.txt
haha
//读文件
int main()
{
umask(0);
//0.打开文件,获取文件描述符(后面介绍)
int fd = open("./1.txt",O_RDWR | O_CREAT ,0644);
//1.读取文件,输出到标准输出上
char buf[1024]={0};
ssize_t read_size= read(fd,buf,sizeof(buf)-1);
if(read_size<0)
{
perror("read");
return -1;
}
std::cout<<buf<<std::endl;
}
//程序执行结果
[skin@bogon Git]$ ./a.out
haha
1.上面的程序中引入一个概念,文件描述符
文件描述符:文件描述符是用来控制文件的,它是文件的句柄,拿到一个文件的描述符, 你就可以对这个文件"为所欲为",操作着它的一切。
2.文件描述符在内核中的表示
a.由图可以知道,一个进程所创建的文件信息也存在PCB中 b.一个进程开启时默认创建三个文件即 :0,1,2 c.file_array:其实就是一个数组,用来保存文件描述符的。 d.文件描述符总是从最小下标的位置开始创建,依次增加。
下面通过一个例子来看下文件描述符的创建规则:
13 int main()
14 {
15
16 //0.关闭标准输出即 1
17 close(1);
18 //1.新建一个文件
19 umask(0);
20 int fd = open("./1.txt",O_RDWR |O_CREAT,0644);
21
22 //2.向标准输出写入"hello,world"
23 char buf[]="hello,world\n";
24 write(1,buf,strlen(buf));
25
26 }
//程序执行结果
[skin@bogon Git]$ ./a.out
[skin@bogon Git]$ cat 1.txt
hello,world
上述程序问什么呢?明明是写到标准输出上去了,为什么会写入1.txt文件呢?这是上面我们所说的文件描述符的创建规则,总是从最小的下标开始创建,所有当关闭1文件描述符,再创建一个新的文件时,就会使用1,因为它是最小的且没有使用的。如图
- 03.重定向
- -
1.什么是重定向?顾名思义就是将原来的方向进行改变,换个方向。
2.上面讲的实例,就是一个简单的重定向,明明说出到标准输出却写入了文件。
3.重定向有自己标准的函数,上述的方法不是个人觉得不是很喜欢,所以看一下重定向的API
下面实例用一下,实现和上面一样的效果:
int main()
{
//1.新建一个文件
umask(0);
int fd = open("./1.txt",O_RDWR |O_CREAT,0644);
//2.重定向文件描述符
dup2(fd,1);
//2.向标准输出写入"hello,world"
char buf[]="hello,world\n";
write(1,buf,strlen(buf));
}
//程序执行结果
[skin@bogon Git]$ ./a.out
[skin@bogon Git]$ cat 1.txt
hello,world
- 04.文件系统
1.文件系统的示意图:
超级块:记录文件系统本身的信息
inode:是文件的索引,记录着文件数据在后面数据块的位置。
数据块:用来真正的存储文件的数据。
为什么用这样的结果来存储文件呢?这样数据可以离散的存储,提高了磁盘的利用率。
2.文件操作的原理
解释一下上图:
1.首先用ls -i filename 进行查看文件inode节点号,也就其索引值,拿到索引值,
2.根据索引值到inode节点上去找到对应的inode节点,取出对应inode节点。
3.inode节点里面存储的是数据在数据块中存储的位置,是一个有序的列表,所以按序从数据块拿出,就是这个文件真正存储的数据。
3.说到这里,就必须说一下软硬链接了
- 05.简述静态库,动态库
- -
静态库:是程序编译器期间用来链接,一起生成可执行文件,在生成可执行文件后,不需要静态库了,即使你把静态库删除了,也不会影响可执行文件的执行。
动态库:程序运行期间去查找库,并且动态链接上,完成可执行文件的执行。动态库可以多个程序共享,都可以进行链接。所以说动态库在一定程度上让可执行文件遍的更小了,节约了空间。