目录
- 3 系统调用IO
- 3.1 文件描述符
- 3.1.1 FILE结构体
- 3.2.2 文件描述符
- 3.3 open、close、read、write、lseek
- 3.3.1 文件权限
- 3.3.2 open
- 3.3.3 close
- 3.3.4 read
- 3.3.5 write
- 3.3.6 lseek
- 3.3.7 代码示例
- 文件io和标准io的区别
橙色
3 系统调用IO
3.1 文件描述符
3.1.1 FILE结构体
查看stdio.h
头文件中,有FILE
结构体的定义:
//stdio.h
typedef struct _iobuf {
char* _ptr; //文件输入的下一个位置
int _cnt; //当前缓冲区的相对位置
char* _base; //文件初始位置
int _flag; //文件标志
int _file; //文件有效性
int _charbuf; //缓冲区是否可读取
int _bufsiz; //缓冲区字节数
char* _tmpfname; //临时文件名
} FILE;
其中_file
就是文件描述符。
3.2.2 文件描述符
3.3 open、close、read、write、lseek
3.3.1 文件权限
关于文件权限的相关内容请参考该篇博客:【Linux】用户管理(添加用户、修改密码、删除用户、查询用户信息、切换用户、查看当前用户、用户组)
另外补充一个知识点:
umask
Linux具有默认权限:
- 一个目录被创建,默认权限是
drwxrwxrwx
,即777 - 一个普通文件被创建,默认权限是
-rw-rw-rw-
,即666
但实际上所创建的文件和目录,看到的权限往往不是上面这个值。原因就是创建文件或目录的时候还要受到 umask
的影响。umask值表明了需要从默认权限中去掉哪些权限来成为最终的默认权限值。
3.3.2 open
open用于打开或创建一个文件或者设备。
所在头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
函数原型:
int open(const char *pathname, int flags);
//当flag包含O_CREAT时,下面这个三个参数的
int open(const char *pathname, int flags, mode_t mode);
- 将准备打开的文件或是设备的名字作为参数path传给函数,flags用来指定文件访问模式。
- open系统调用成功返回一个新的文件描述符,失败返回-1。
其中,flags是由必需文件访问模式和可选模式一起构成的(通过按位或|
):
3.3.3 close
3.3.4 read
3.3.5 write
3.3.6 lseek
3.3.7 代码示例
一个copy的代码:
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFFSIZE 1024
int main(int argc,char** argv){
int len,ret,pos;
int fds,fdd;
char buf[BUFFSIZE];
if(argc<3){
fprintf(stderr,"input error");
}
fds=open(argv[1],O_RDONLY);
if(fds<0){
perror("open");
}
fdd=open(argv[2],O_WRONLY|O_CREAT,O_TRUNC,0600);
if(fdd<0){
close(fds);
perror("open");
}
while(1)
{
len=read(fds,buf,BUFFSIZE);
if(len<0)
{
perror("read");
break;
}
else if(len==0)
{
break;
}
pos=0;
while(len >0)
{
ret=write(fdd,buf+pos,len);
if(ret<0)
{
perror("write");
break;
}
len-=ret;
pos+=ret;
}
}
close(fdd);
close(fds);
exit(0);
}
文件io和标准io的区别
文件io(系统调用io)响应速度快,它在输出端没有缓冲区,有数据来了,就直接处理;标准io吞吐量更大,因为它有缓冲区,所以是等满足一定条件了,再把缓冲区中的数据一起发送出去。
从实际的用户体验来说,吞吐量大会感觉更快。所以在文件io和标准io都能够调用的时候,选择标准io是更好的。
提醒:文件io和标准io不可以混用
一个小例子:
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#define BUFFSIZE 1024
int main(){
putchar('a');
write(1,"b",1);
putchar('a');
write(1,"b",1);
putchar('a');
write(1,"b",1);
exit(0);
}
输出结果:bbbaaa
很好的印证了上面所说的标准IO和系统IO的区别,write是系统IO,所以立即输出;而putchar是标准IO,有缓冲区,并未立即输出。