练习open/read/write/close等文件相关系统调用接口,纵向对比fd与FILE结构体:
open原型:
int open(const char *pathname,int flags,mode_t mode);
第一个参数是要打开或创建的目标文件
第二个参数是打开文件的方式
O_RDONLY:只读打开 O_WRONLY:只写打开 O_RDWR:读,写打开
O_CREAT:若文件不存在,则创建它,需要使用mode选项,来指明新文件的权限
O_APPEND:追加写
第三个参数是创建文件的默认权限,可以用八进制表示
返回值:成功:返回一个新的文件描述符,失败:返回-1
read的函数原型:
ssize_t read(int fd,void *buf,size_t count);
第一个参数:文件描述符
第二个参数:定义的缓冲区,例如传一个数组指针
第三个参数:要读入数据的大小
返回值:成功:返回读取的字节数, 错误:返回-1
write的函数原型
ssize_t write(int fd,const void *buf,size_t count);
第一个参数:文件描述符
第二个参数:写入的内容
第三个参数:写入的字节数
返回值:成功返回写入的字节数, 错误:返回-1
close的函数原型
int close(int fd);
返回值:
返回0表示成功,返回-1表示失败
以上所说的系统调用接口均可使用 man 2 系统调用符 来查询,一看就懂
代码:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
int main()
{
umask(0);
int fd=open("file",O_WRONLY|O_CREAT,0644);//open函数,0644代表权限
if(fd<0){
perror("open");
return 1;
}
int count=3;
const char* str="hello linux\n";
int len=strlen(str);
while(count--)
{
write(fd,str,len);
}
}
运行结果:
int main()
{
int fd=open("file",O_RDONLY);
if(fd<0)
{
perror("open");
return 1;
}
char buf[6]={};
while(1){
int a=read(fd,buf,3);
if(a>0){
printf("%s",buf);
}
else{
break;
}
}
close(fd);
return 0;
}
运行结果:
fd和FILE对比:
1.fd属于系统库,有文件描述符
2.FILE属于C标准库,属于结构体
linux下进程默认情况下会打开3个缺省打开的文件描述符分别是0,1,2 对应的物理设备是键盘,显示器,显示器
输出重定向操作:
int main()
{
close(1);
int fd=open("myfile",O_WRONLY|O_CREAT,0644);
if(fd<0)
{
perror("open");
return 1;
}
printf("hello linux\n");
fflush(stdout);
close(fd);
return 0;
}
看上面的代码,本来应该输出到显示器上,但是由于关掉了 文件描述符(1),不能输出到显示器上
就会输出到最近创建的文件里面,叫做重定向。
运行结果如下:
其操作原理如下图所示:
文件有两种链接属性:
软链接:一个独立的文件独立的inode,文件里面放的是原文件的路径
硬链接:与原文件是同一个inode,多了一个文件名和inode的映射关系,相当于重命名
一个文件一个inode(硬链接除外)
inode解释如下图
编写简单的add/sub 函数并打包成动/静态库,并分别使用
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中,程序运行的时候将不在需要静态库
动态库(.so):程序在运行的时候才会去链接动态库代码,多个程序共享使用库代码
生成静态库:
add.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int x,int y);
#endif //__ADD_H__
add.c
#include"add.h"
int add(int x,int y)
{
return x+y;
}
sub.h
#ifndef __SUB_H__
#define __SUB_H__
int sub(int x,int y);
#endif //__SUB_H__
sub.c
#include"sub.h"
int sub(int x,int y)
{
return x-y;
}
test.c
int main()
{
int x=10;
int y=5;
printf("%d+%d=%d\n",x,y,add(x,y));
printf("%d-%d=%d\n",x,y,sub(x,y));
return 0;
}
运行结果:
生成动态库:
1.shared:表示生成共享库格式
2.fPIC:产生位置无关码
3.库名规则:libxxxx.so
使用动态库:
l:链接动态库,只要库名即可
L:链接库所在的路径
直接运行./a.out是不行的,需要执行下列操作