【系统调用IO】open、close、read、write、lseek

目录

  • 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 文件描述符

【系统调用IO】open、close、read、write、lseek_第1张图片

3.3 open、close、read、write、lseek

3.3.1 文件权限

关于文件权限的相关内容请参考该篇博客:【Linux】用户管理(添加用户、修改密码、删除用户、查询用户信息、切换用户、查看当前用户、用户组)

另外补充一个知识点:

umask

Linux具有默认权限:

  • 一个目录被创建,默认权限是drwxrwxrwx,即777
  • 一个普通文件被创建,默认权限是-rw-rw-rw-,即666

但实际上所创建的文件和目录,看到的权限往往不是上面这个值。原因就是创建文件或目录的时候还要受到 umask 的影响。umask值表明了需要从默认权限中去掉哪些权限来成为最终的默认权限值。

【系统调用IO】open、close、read、write、lseek_第2张图片

3.3.2 open

open用于打开或创建一个文件或者设备。

所在头文件:

#include 
#include 
#include 

函数原型:

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是由必需文件访问模式和可选模式一起构成的(通过按位或|):
【系统调用IO】open、close、read、write、lseek_第3张图片

3.3.3 close

【系统调用IO】open、close、read、write、lseek_第4张图片

3.3.4 read

【系统调用IO】open、close、read、write、lseek_第5张图片

3.3.5 write

【系统调用IO】open、close、read、write、lseek_第6张图片

3.3.6 lseek

【系统调用IO】open、close、read、write、lseek_第7张图片

3.3.7 代码示例

一个copy的代码:

#include
#include
#include 
#include 
#include 
#include 
#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
#include
#include 
#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,有缓冲区,并未立即输出。

你可能感兴趣的:(#,Linux系统编程入门,linux)