3.1 文件描述符

  文件IO 系统调用是不带缓存的,文件 I/O 系统调用不是 ANSI C 的组成部分,是 POSIX 的组成部分。

  系统调用与C库:

  

  C库函数的IO 的底层还是调用系统调用 I/O。

  需要运行速度很快的时候采用 文件IO系统调用。

  FILE 结构体中有 文件描述符成员 fd,标准C的IO依然是通过 fd 来操作文件,系统调用的 文件 IO 直接使用 fd 来操作。

  • 标准库函数:遵守 ISO 标准,基于流的 I/O,对文件指针(FILE结构体)进行操作
  • 系统调用:兼容 POSIX 标准,基于文件描述符的 I/O,对文件描述符进行操作
  • 文件描述符:
    • 对于内核而言,所有打开文件都由文件描述符引用。文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,用 open 或 creat 返回的文件描述符标识该文件,将其作为参数传送给 read 或 write。
    • 在 POSIX 应用程序中,整数0、1、2 被替换成符号常熟 STDIN_FILENO 、STDOUT_FILENO 或STDERR_FILENO。这些常数都定义在头文件 <unistd.h> 中。
    • 文件描述符的范围是 0-- OPEN_MAX。Linux为1024(允许每个进程打开1024个文件)  

  文件描述符可以和文件指针相互转换:

  • 标准文件指针

    • stdin:0
    • stdout:1
    • stderr:2  
  • fdopen(): FILE *fdopen(int fd, const char *mode)
    • 文件描述符 转化为 文件指针  
  • fileno():int fileno(FILE *stream)
    • 文件指针转换为文件描述符  

3.2 文件IO 系统调用

3.2.1 open 函数--- 打开文件

  头文件:

  #include<sys/types.h>
  #include<sys/stat.h>
  #include<fcntl.h>

 int open( const char * pathname, int flags);  //打开已经存在的文件时候用
int open( const char * pathname,int flags, mode_t mode);  //若是需要创建文件使用此函数
  • 参数pathname 指向欲打开的文件路径字符串。
  • * 参数 flags 所能使用的标志:
    • * O_RDONLY 以只读方式打开文件
    • * O_WRONLY 以只写方式打开文件
    • * O_RDWR 以可读写方式打开文件
    • * 上述三种旗标是互斥的,也就是不可同时使用,但可与下列的标志利用OR(|)运算符组合。
    • * O_CREAT 若欲打开的文件不存在则按照 mode 参数指定的文件权限来创建文件。
    • * O_EXCL 如果O_CREAT 也被设置,此指令会去检查文件是否存在。文件若不存在则建立该文件,否则将导致打开文件错误。此外,若O_CREAT与O_EXCL同时设置,并且欲打开的文件为符号连接,则会打开文件失败。在网络文件系统仅从操作时却没有保证
    • * O_NOCTTY 如果欲打开的文件为终端机设备时,则不会将该终端机当成进程控制终端机。
    • * O_TRUNC 若文件存在并且以只读或只写的方式打开时,此标志会令文件长度清为0,而原来存于该文件的资料也会消失。
    • * O_APPEND 当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式加入到文件后面。
    • * O_NONBLOCK 以不可阻塞的方式打开文件,也就是无论有无数据读取或等待,都会立即返回进程之中。pathname 指的是一个FIFO、一个块特殊文件或一个字符特殊文件。
    • * O_NDELAY 同O_NONBLOCK。
    • * O_SYNC 以同步的方式打开文件。
    • * O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接,则会令打开文件失败。
    • * O_DIRECTORY 如果参数pathname 所指的文件不是一个目录,则会令打开文件失败。此为Linux2.2以后特有的旗标,以避免一些系统安全问题
  • * 参数 mode 则有下列数种组合,只有在建立新文件时才会生效,此外真正建文件时的权限会受到umask值所影响,因此该文件权限应该为(mode-umaks)。
    • * S_IRWXU,00700 权限,代表该文件所有者具有可读、可写及可执行的权限。
    • * S_IRUSR 或 S_IREAD,00400 权限,代表该文件所有者具有可读取的权限。
    • * S_IWUSR 或 S_IWRITE,00200 权限,代表该文件所有者具有可写入的权限。
    • * S_IXUSR 或 S_IEXEC,00100 权限,代表该文件所有者具有可执行的权限。
    • * S_IRWXG 00070权限,代表该文件用户组具有可读、可写及可执行的权限。
    • * S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。
    • * S_IWGRP 00020权限,代表该文件用户组具有可写入的权限。
    • * S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限。
    • * S_IRWXO 00007权限,代表其他用户具有可读、可写及可执行的权限。
    • * S_IROTH 00004 权限,代表其他用户具有可读的权限
    • * S_IWOTH 00002权限,代表其他用户具有可写入的权限。
    • * S_IXOTH 00001 权限,代表其他用户具有可执行的权限。
  • * 返回值 成功返回文件描述符,失败则返回-1
    • * 错误代码 EEXIST 参数 pathname 所指的文件已存在,却使用了O_CREAT 和 O_EXCL 标志。
    • * EACCESS 参数 pathname 所指的文件不符合所要求测试的权限。
    • * EROFS 欲测试写入权限的文件存在于只读文件系统内
    • * EFAULT 参数 pathname 指针超出可存取内存空间
    • * EINVAL 参数 mode 不正确。
    • * ENAMETOOLONG 参数pathname太长
    • * ENOTDIR 参数pathname不是目录。
    • * ENOMEM 核心内存不足
    • * ELOOP 参数pathname有过多符号连接问题。
    • * EIO I/O 存取错误。
  • 附加说明 使用 access() 作用户认证方面的判断要特别小心,例如在 access() 后再作 open()空文件可能会造成系统安全上的问题。

3.2.2 creat 函数--- 创建文件

 #include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int creat(const char * pathname, mode_t mode);
  • * 相关函数 read,write,fcntl,close,link,stat,umask,unlink,fopen
  • * 函数说明
    • 参数pathname指向欲建立的文件路径字符串。Creat()相当于使用下列的调用方式调用open()
    • * open(const char * pathname ,(O_CREAT|O_WRONLY|O_TRUNC), mode);
  • * 参数: 关于参数mode请参考open()函数。
  • * 返回值
    • creat()会返回新的文件描述词,若有错误发生则会返回-1,并把错误代码设给errno。
  • * 错误代码
    • EEXIST 参数 pathname 所指的文件已存在,却使用了O_CREAT 和 O_EXCL 标志。
    • * EACCESS 参数 pathname 所指的文件不符合所要求测试的权限。
    • * EROFS 欲测试写入权限的文件存在于只读文件系统内
    • * EFAULT 参数 pathname 指针超出可存取内存空间
    • * EINVAL 参数 mode 不正确。
    • * ENAMETOOLONG 参数pathname太长
    • * ENOTDIR 参数pathname不是目录。
    • * ENOMEM 核心内存不足
    • * ELOOP 参数pathname有过多符号连接问题。
    • * EMFILE 已达到进程可同时打开的文件数上限
    • * ENFILE 已达到系统可同时打开的文件数上限
  • * 附件说明
    • creat()无法建立特别的设备文件,如果需要请使用mknod()。
    • creat 的一个不足之处是它只以只写的方式打开所创建的文件。

3.2.3 close 函数--- 文件关闭

 #include<unistd.h>
int close(int fd);
  • * 函数说明

    • 当使用完文件后若已不再需要则可使用close()关闭该文件,close()会让数据写回磁盘,并释放该文件所占用的资源。
  • * 参数 fd 为先前由 open() 或 creat() 所返回的文件描述词。
  • * 返回值
    • 若文件顺利关闭则返回0,发生错误时返回-1。
  • * 错误代码
    • EBADF 参数fd 非有效的文件描述词或该文件已关闭。
  • * 附加说明
    • 虽然在进程结束时,系统会自动关闭已打开的文件,但仍建议自行关闭文件,并确实检查返回值。
    • 当一个进程终止时,它所有的打开文件都由内核自动关闭

三、文件IO——系统调用的更多相关文章

  1. 三、文件IO——系统调用(续)

    3.2.4 read 函数--- 读文件 read(由已打开的文件读取数据) #include<unistd.h> ssize_t read(int fd, void * buf, siz ...

  2. 文件IO——将文件dfs的文件内容第三个字节之后的内容复制到文件dfd中

    /* 使用文件IO将文件fds中的内容复制到文件fdd中去 1.创建两个文件描述符 2.使用open()方法分别以只读只写方式将文件描述符符文件连接 3.将读位置后移三位 4.将fds内容存储到缓冲区 ...

  3. 文件IO函数和标准IO库的区别

    摘自 http://blog.chinaunix.net/uid-26565142-id-3051729.html 1,文件IO函数,在Unix中,有如下5个:open,read,write,lsee ...

  4. (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  5. 文件IO

    在unix世界中视一切为文件,无论最基本的文本文件还是网络设备或是u盘,在内核看来它们的本质都是一样的.大多数文件IO操作只需要用到5个函数:open . read . write . lseek 以 ...

  6. select、poll、epoll三组IO复用

    int select(int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,struct timeval* timeout)//其中n ...

  7. UNIX高级环境编程(14)文件IO - O_DIRECT和O_SYNC详解 < 海棠花溪 >

    春天来了,除了工作学习,大家也要注意锻炼身体,多出去运动运动.  上周末在元大都遗址公园海棠花溪拍的海棠花.   进入正题. O_DIRECT和O_SYNC是系统调用open的flag参数.通过指定o ...

  8. (代码篇)从基础文件IO说起虚拟内存,内存文件映射,零拷贝

    上一篇讲解了基础文件IO的理论发展,这里结合java看看各项理论的具体实现. 传统IO-intsmaze 传统文件IO操作的基础代码如下: FileInputStream in = new FileI ...

  9. (理论篇)从基础文件IO说起虚拟内存,内存文件映射,零拷贝

    为了快速构建项目,使用高性能框架是我的职责,但若不去深究底层的细节会让我失去对技术的热爱. 探究的过程是痛苦并激动的,痛苦在于完全理解甚至要十天半月甚至没有机会去应用,激动在于技术的相同性,新的框架不 ...

随机推荐

  1. failover swarm 故障转移

    #故障转移 Failover #当其中一个节点关闭宕机时,其节点中的service会转移到另一个节点上.Swarm会检测到node1发生故障并把此故障节点的状态标记为Down; docker node ...

  2. mybatis 二级缓存

    Mybatis读取缓存次序: 先从二级缓存中获取数据,如果有直接获取,如果没有进行下一步: 从一级缓存中取数据,有直接获取,如果没有进行下一步: 到数据库中进行查询,并保存到一级缓存中: 当sqlSe ...

  3. wildfly access log 开启

    对于一个网站来说,访问日志,即access_log,是一项很重要的功能.利用它,我们可以统计出很多有用的信息,我们可以利用log来对整个网站的运行做有效的监控和分析,从而提升网站的性能. 在WildF ...

  4. yd的汇总

    因为是我这只蒟蒻个人的汇总嘛,可能有些奇♂怪的东西或者不规范的语言出现啦,见谅见谅 搬了一些到知识汇总里,删了一些过时和无用的,少了好多=.= 1.STL_queue 经实践验证,!qs.empty( ...

  5. [bzoj1717][Milk Patterns 产奶的模式]

    题目链接 思路 先求出后缀数组,并且求出LCP.二分一下长度len.check的时候就是看有没有连续的k个后缀的LCP大于len.也就是判断是不是有连续的k-1个height大于len. 代码 #in ...

  6. JavaScript FormData的详细介绍及使用

    本文转自:https://blog.csdn.net/liupeifeng3514/article/details/78988001 FormData的详细介绍及使用请点击此处,那里对FormData ...

  7. 为什么要用PolyFill(JS中的修补匠)

    var users = [{name:"zhangsan",age:18},{name:"jack",age:20}]; 这是一个对象数组.如果我们要查询名字为 ...

  8. prototype 与 proto的关系是什么:

    __proto__是什么? 我们在这里简单地说下.每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto_ ...

  9. Javascript的组成——EMACScript、DOM、BOM

    EMACScript:一种规范,JS必须准守它的约定,JS的核心. DOM:文档对象模型,W3C标准,JS访问HTML文档的接口. BOM:浏览器对象模型,没有统一的标准.JS访问浏览器的接口. EM ...

  10. Collection中的迭代器

    迭代器:boolean hasNext() 判断集合中是否还有没有被取出数据nexe() 取出集合中下一个元素package cn.lijun.demo4; import java.util.Arra ...