第三章 文件IO

  • 对于内核而言,所有打开的文件都通过文件描述符引用,文件描述符是一个非负整数

    文件描述符 标准 符号常量
    文件描述符0 标准输入 STDIN_FILENO
    文件描述符1 标准输出 STDOUT_FILENO
    文件描述符2 标准错误 STDERR_FILENO
  • 函数open和openat---打开文件

    int open(const char *path, int oflag, .../*mode_t mode*/)
    
    int openat(int fd,const char *path, int oflag, .../*mode_t mode*/)
            两函数的返回值:若成功,返回文件描述符,若出错,返回-1
    
    • path---要打开或创建文件的名字
    • oflag---用来说明此函数的多个选项
    • fd---把open和openat函数区分开,有下列三种情况
      1. path参数指定的是绝对路径名,在这种情况下,fd参数被忽略,openat函数相当于open
      2. path参数指定的是相对路径名,fd参数指出了相对路径名在文件系统中的开始地址。fd参数是通过打开相对路径名所在的目录来获取
      3. path参数指定的是相对路径名,fd参数具有特殊值AT_FDCWD。在这种情况下,路径名在当前工作目录中获取,openat函数在操作上和open函数相似
  • 函数creat---创建文件

    int creat(const char *path, mode_t mode)
        返回值:若成功,返回为只写打开的文件描述符。若出错,返回-1
    
  • 函数close---关闭文件

    int close(int fd)
        返回值:若成功,返回0。若出错,返回-1
    
    • 关闭一个文件时会释放该进程加在改文件上的所有记录锁
  • 函数lseek---显示地为一个打开文件设置偏移量

    off_t lseek(int fd, off_t offset, int whence)
        返回值:若成功,返回新的文件偏移量。若出错,返回-1
    

    对参数offset的解释和参数whence的值有关

    • 若whence = SEEK_SET,则将该文件的偏移量设置为距文件开始处offset个字节
    • 若whence = SEEK_CUR,则将该文件的偏移量设置为其当前值加offset,offset可正可负
    • 若whence = SEEK_END,则将该文件的偏移量设置为文件长度加offset,offset可正可负
  • 函数read---读数据

    ssize_t read(int fd, void *buf,size_t nbytes)
        返回值:读到的字节数,若已到文件尾,返回0。若出错,返回-1
    
    • 有多种情况可使实际读到的字节数少于要求读的字节数
  • 函数write---写数据

    ssize_t write(int fd, const void *buf,size_t nbytes)
        返回值:若成功,返回已写的字节数。若出错,返回-1
    
  • 单个进程打开文件时内核数据结构图

image
  • 两个独立进程各自打开了同一个文件,有如下关系图
image
  • 多个进程读取同一文件都能正常工作。每个进程都有它自己的文件表项,其中也有它自己的当前文件偏移量。但是,当多个进程写同一个文件时,则可能产生预想不到的结果

  • 原子操作指的是由多步组成的一个操作,如果原子操作被执行,要么执行完所有步骤,要么一步也不执行,不可能执行所有步骤中的一个子集

  • 函数dup和dup2---复制一个现有的文件描述符

    int dup(int fd)
    
    int dup2(int fd,int fd2);
        返回值:若成功,返回新的文件描述符。若出错,返回-1
    
    • fd---将要复制的文件描述符
    • fd2---指定新描述符的值(将要返回的)
    • dup返回的新文件描述符一定是当前可用文件描述符中的最小数值
    • dup2是一个原子操作,
    close(fd2);
    fcntl(fd,F_DUPFD,fd2);
    
  • 函数fcntl---改变打开已经打开的文件的属性

    int fcntl(int fd, int cmd, .../* int arg */)
        返回值:若成功,则依赖于cmd。若出错,返回-1
    
    • fcntl有以下5中功能
      • 复制一个已有的描述符(cmd = F_DUPFD 或 F_DUPFD_CLOEXEC)
      • 获取/设置文件描述符标志(cmd = F_GETFD 或 F_SETFD)
      • 获取/设置文件状态标志(cmd = F_GETFL 或 F_SETFL)
      • 获取/设置异步I/O所有权(cmd = F_GETOWN 或 F_SETOWN)
      • 获取/设置记录锁(cmd = F_GETLK、F_SETLK 或 F_SETLKW)
    • 在修改文件描述符标志或文件状态标志时必须谨慎,先要获得现在的标志值,然后按照期望修改,最后设置新标志值。不能只执行F_SETFD或F_SETFL命令,这样会关闭以前设置的标志位
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文摘抄自linux基础编程 IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作。那么我们对与外部设...
    VD2012阅读 4,578评论 0 2
  • 大纲 一.Socket简介 二.BSD Socket编程准备 1.地址 2.端口 3.网络字节序 4.半相关与全相...
    VD2012阅读 7,156评论 0 5
  • https://nodejs.org/api/documentation.html 工具模块 Assert 测试 ...
    KeKeMars阅读 11,499评论 0 6
  • 1.文件描述符 所有执行I/O操作的系统调用都以文件描述符(一个非负整数)来指代打开的文件。文件描述符用以表示所有...
    666真666阅读 4,818评论 0 2
  • 文殊菩萨,梵名Mañjuśrī[1] ,音译作文殊师利、曼殊室利、满祖室哩,意译为妙德、妙吉祥、妙乐、法...
    060宋丹阅读 3,940评论 0 2