文件io:二、系统io和api
1.前言先讲讲为什么要打开文件或者关闭我们已知linux的各种东西都是文件也就是io。你不打开文件你怎么写程序和编程因此我们需要打开文件编写和操作文件然后再关闭文件。1.1打开文件需要满足的前置条件在每次c语言编写时添加3个头文件这几个头文件的功能是打开一个指定的文件并获得文件描述符没有文件的时候会创建一个新的文件。如果你要关闭文件——你也不想你的文件被打开了就关不了吧需要添加一个#includeunistd.h头文件文件的关闭会在下文提到。1.1.1 open函数介绍我们拿open函数作为一个原型来举例open函数有2种一种有2个参数另一种有3个参数。根据实际情况进行选择就好。pathname是你即将要打开的文件假设你已经在根目录新建了一个nb666.txt文件那么pathname就是nb666.txt。flags就是打开文件后你要进行的操作看上表里的内容根据你需要的操作选择对应的flag。mode如果你选择了有3个参数的open函数那么mode就是你要设定的权限。注意当创建一个新文件时需要用第三个参数指定新文件的权限否则新文件的权限是随机值。1.1.2 注意事项当打开一个已存在的文件时指定两个参数即可。模式flags可以使用位或的方式来同时指定多个模式。模式flags中O_NOCTTY主要用在后台精灵进程阻止这些精灵进程拥有控制终端。精灵进程通常称为守护进程英文Daemon是在后台运行的一种特殊进程没有控制终端独立于用户交互专门执行特定任务或等待处理某些事件。注意怕一些小傻瓜不理解pathnameflagsmode统称为参数。1.1.3 示例代码int main(void) { int fd; //接下来举例两种open函数一种是2个参数的一种是3个参数的 // 以下三种打开方式都要求文件已存在否则失败返回 //这是两个参数的 fd open(a.txt, O_RDWR); // 以可读可写方式打开 fd open(a.txt, O_RDONLY); // 以只读方式打开 fd open(a.txt, O_WRONLY); // 以只写方式打开 // 1. 如果文件不存在则创建该文件并设置其权限为0644 // 2. 如果文件已存在则失败返回 //这是3个参数的 fd open(a.txt, O_RDWR|O_CREAT|O_EXCL, 0644); // 以可读可写方式打开 fd open(a.txt, O_RDONLY|O_CREAT|O_EXCL, 0644); // 以只读方式打开 fd open(a.txt, O_WRONLY|O_CREAT|O_EXCL, 0644); // 以只写方式打开 // 1. 如果文件不存在则创建该文件并设置其权限为0644 // 2. 如果文件已存在则清空该文件的原有内容 //这也是3个参数的 fd open(a.txt, O_RDWR|O_CREAT|O_TRUNC, 0644); // 以可读可写方式打开 fd open(a.txt, O_RDONLY|O_CREAT|O_TRUNC, 0644); // 以只读方式打开 fd open(a.txt, O_WRONLY|O_CREAT|O_TRUNC, 0644); // 以只写方式打开 // 以下三种打开方式都要求文件已存在否则失败返回 fd open(a.txt, O_RDWR|O_APPEND, 0644); // 以可读可写方式追加文件内容 fd open(a.txt, O_WRONLY|O_APPEND, 0644); // 以只写方式追加文件内容 } 文件权限掩码 创建目录或者文件的时候 文件权限 有一个概念是umask 使用命令umask查看 例如0002八进制 000 000 000 010 文件权限 mode (~umask) ~umask 111 111 111 101 mode 0644 000 110 100 100 111 111 111 101 000 110 100 100 0644 mode 0777 000 111 111 111 111 111 111 101 000 111 111 101 0775 umask0002 八进制 设置的权限 0777 0777-0002775 常见umask 0000不屏蔽 0002屏蔽other用户的写权限 002207770755屏蔽除了自己之外所有用户的写入权限 umask 0077 07770700会使得文件和目录仅对所有者可见其他用户无任何权限1.1.4 关闭文件为什么要关闭文件当不再使用一个文件时应当关闭该文件防止系统资源浪费。对同一文件重复执行关闭操作会失败返回不会有其他副作用。文件描述符的资源有限打开文件后一定要记得关闭。示例代码fd的取值预设的最大可打开文件描述符数量0个到1023个可以改这个范围前提是你有需求否则一般不修改所以不讲修改操作。1.2 标准库函数的错误发生的情况前言在所有的库函数中如果调用过程出错了那么该函数除了会返回一个特定的数据来告诉用户调用失效之外还都会去修改一个大家共同的全局错误码errno我们可以通过这个错误码来进一步确认究竟是什么错误。前置条件添加一个头文件#include errno.h使用方法输出错误代码printf(failed,strerror(errno));示例代码注意如果库函数、系统调用出错了全局错误码 errno 会随之改变如果库函数、系统调用没出错全局错误码 errno 不会改变这个可以展开讲讲看2.1一个库函数、系统调用出错后若未及时处理错误码则错误码可能会被随后的其他函数修改也就是说本来出现的错误码被新出现的错误码顶掉了意味着你要即使处理你的错误。1.2.1 为什么成功运行时错误码不改变我们已经知道库函数、系统调用没出错全局错误码 errno 是不会改变的。比如我运行了某个函数出现了以下结果原因这是 C 语言的历史遗留问题errno是一个全局变量在现代 Linux 中其实是线程局部存储函数成功时不去动它是为了避免性能开销这个设计是为了让程序员必须在失败后立即处理errno1.2.3 提取错误码的方法和操作第一种第二种这两种方法的输出结果是一样的输出为
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2425673.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!