文件IO(4)

余生长醉 提交于 2020-02-29 12:19:39

文件IO

open()   头文件 #include<unistd.h>
  • int open(const char *pathname,int flags);
    • pathname:欲打开的文件路径
    • flags:文件打开方式
      • 常用参数  头文件 #include<fcntl.h>
        • O_RDONLY、O_WRONLY、O_RDWR
        • O_APPEND、O_CREAT、O_EXCL、O_TRUNC、O_NUNBLOCK
    • 返回值:
      • 成功:打开文件所得到对应的文件描述符(整数)
      • 失败:-1,设置error
  • int open(const char *pathname,int flags,mod_t mode);
    • pathname:欲打开的文件路径
    • flags:文件打开方式
      • 常用参数
        • O_RDONLY、O_WRONLY、O_RDWR
        • o_APPEND、O_CREAT、O_EXCL、O_TRUNC、O_NUNBLOCK
    • mode:参数3使用的前提是 参数2指定了O_CREAT,取值为八进制数,用来描述文件的访问权限。
      • 创建文件时,指定文件访问权限。权限同时受 umask 影响。结论为:文件权限 = mode & ~umask
    • 返回值:
      • 成功:打开文件所得到对应的文件描述符(整数)
      • 失败:-1,设置error
  • open常见错误:
    1. 打开文件不存在
    2. 以写方式打开只读文件(打开文件没有对应权限)
    3. 以只写方式打开目录
close()
  • int close(int fd);
错误处理函数:与error相关
  • char *strerror(int errnum);
    • printf(“xxx error: %s\n”,strerror(errno));
  • void perror(const char*s);
    • perror(“xxx xxx”);
read()
  • ssize_t read(int fd, void *buf, size_t count);
    • 参数:
      • fd:文件描述符
      • buf:存数据的缓冲区
      • count:缓冲区大小
    • 返回值:
      • 0:读到文件末尾。
      • 成功:读到的字节数
      • 失败:-1,设置error。
      • -1:并且 error = EAGIN 或 EWOULDBLOCK,说明不是read失败,而是read在以非阻塞方式读一个设备文件(网络文件),并且文件无数据。
write()
  • ssize_t write(int fd, const void *buf, size_t count);
    • 参数:
      • fd:文件描述符
      • buf:待写出数据的缓冲区
      • count:数据大小
    • 返回值:
      • 成功:写入的字节数
      • 失败:-1,设置error。
文件描述符
  • PCB进程控制块:本质是 结构体。
  • 成员:文件描述符表。
  • 文件描述符:0/1/2/3/4/…/1023 表中可用的最小的
  • 0 - STDIN_FILENO
  • 1 - STDOUT_FILENO
  • 2 - STDERR_FILENO
阻塞、非阻塞:是设备文件、网络文件的属性
  • 产生阻塞的场景,读设备文件、读网络文件。(读常规文件无阻塞概念)
    • eg:/dev/tty —终端文件
      • open("/dev/tty",O_RDWR|O_NONBLOCK) —设置 /dev/tty 为非阻塞状态。(默认为阻塞状态)
fcntl()
  • int fcntl(int fd, int cmd, … /* arg */ );
  • 改变一个【已经打开】的文件的访问控制属性
  • 参数:
    • F_GETFL:获取文件状态
    • F_SETFL:设置文件状态
  1. int flags = fcntl(fd,F_GETFL);
  2. flgs |= O_NONBLOCK;
  3. fcntl(fd,F_SETFL,flgs);
lseek()

Linux中可使用系统函数 lseek 来修改文件偏移量(读写位置)
每个打开的文件都记录着当前读写位置,打开时读写位置是0,表示文件开头,通常读写多少个字节就会将读写位置往后移多少个字节。但是有一个例外,如果以O_APPEND方式打开,每次写操作都会在文件末尾追加数据,然后将读写位置移到新的文件末尾。lseek()和标准I/O库的 fseek()函数类似,可以移动当前读写位置(或叫偏移量)
注意文件“读”和“写”使用同一偏移位置。

  • off_t lseek(int fd, off_t offset, int whence);
  • 参数:
    • fd:文件描述符
    • offset:偏移量
    • whence:起始偏移位置:SEEK_SET/SEEK_CUR/SEEK_END
  • 返回值:
    • 成功:返回较起始位置偏移量
    • 失败:-1 errno
  • 应用场景:
    1. 文件的“读”、“写”使用同一偏移位置。
    2. 使用 lseek() 获取文件大小
    3. 使用 lseek() 拓展文件大小:要想使文件大小真正拓展,必须引起IO操作。
      • 使用 truncate() 函数,直接拓展文件。
传入参数:
  1. 指针作为函数参数
  2. 通常有 const 关键字修饰
  3. 指针指向有效区域,在函数内部做读操作
传出参数:
  1. 指针作为函数参数
  2. 在函数调用之前,指针指向的空间可以无意义,但必须有效
  3. 在函数内部,做写操作
  4. 函数调用结束后,充当函数返回值
传入传出参数:
  1. 指针作为函数参数
  2. 在函数调用之前,指针指向的空间有实际意义
  3. 在函数内部,先做读操作,后做写操作
  4. 函数调用结束后,充当函数返回值

2019 ZhiZDK 如转载请声明。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!