文件IO——open函数的参数flags详解

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

前言

在命令行中使用“man 2 open”可以获知open这个文件IO API的使用方法。

open函数的模型有两种,根据需要选择其中一种即可。

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

两种函数模型中都有flags这个标志,它表示对文件的权限设置以及其他的一些设置,使用方法都像下面这样。

file_fd=open("a.txt", O_WRONLY | O_TRUNC | …… )

1、O_RDONLY、O_WRONLY、O_RDWR

Linux中的文件有读写权限,使用open函数打开文件时,也可以附带一定的权限说明。

比如O_RDONLY就表示以只读方式打开,O_WRONLY表示以只写方式打开,O_RDWR表示以可读可写方式打开。

当附带权限说明后,打开的文件就只能按照这种权限来操作。

2、O_APPEND、O_TRUNC

当使用open函数打开一个内部有内容的文件时,有如下情况:

(1)如果使用O_TRUNC标志,则原来的内容会被丢弃。

(2)如果使用O_APPEND标志,则新写入的内容会接续到原来内容的后面。

(3)默认不使用O_APPEND 和 O_TRUNC标志时,则原来文件中的内容保持不变。

(4)如果O_APPEND和O_TRUNC同时出现,则O_TRUNC将O_APPEND屏蔽掉。

3、O_CREAT、O_EXCL

当使用open函数打开一个文件,如果这个文件不存在,则会打开文件错误。

使用O_CREAT标志后,如果想要打开的文件不存在,则去创建该文件并打开它;如果想要打开的文件存在,则重新创建这个文件,原来的内容会消除。使用这个属性时,最好明确地知道要打开的文件是不存在的,因为如果文件存在,新创建的文件会覆盖已经存在的文件,导致误删问题。

使用O_CREAT和O_EXCL标志后,如果想打开的文件不存在时,则去创建这个文件;如果想打开的文件存在,则报错。

open函数在使用O_CREAT标志去创建文件时,可以使用第三个参数mode来指定要创建的文件的权限。mode使用4个数字来指定权限的,其中后面三个很重要,对应我们要创建的这个文件的权限标志,比如创建一个可读可写不可执行的文件就用0666。

4、O_NONBLOCK

打开文件默认是阻塞式的,如果你希望以非阻塞的方式打开文件,则要添加O_NONBLOCK标志。另外,这个标志只用于设备文件,而不用于普通文件。

补充说明

(1)阻塞与非阻塞的定义

如果一个函数是阻塞式的,调用这个函数时,函数有可能被卡住,即这个函数内部要完成的事情条件不具备,当前没法做,要等待条件成熟,函数被阻塞住了就不能立刻返回。如果一个函数是非阻塞式的,调用这个函数后会立即返回,但是函数有没有完成任务则不确定。

(2)阻塞与和非阻塞的对比

它们是两种不同的设计思路,并没有好坏之分。总的来说,阻塞式的结果有保障但是时间没保障,非阻塞式的时间有保障但是结果没保障。

操作系统提供的API和由API封装而成的库函数,有很多被设计为阻塞式或者非阻塞式的,应用程度调用这些函数时,需要特别注意。

5、O_SYNC

注意这个标志是写在open函数中的,然后影响write函数的。

open函数没有O_SYNC标志时,write函数将内容写入底层缓冲区即可返回。(然后OS会在合适的时机,将buf中的内容一次性的同步到硬盘中。这种设计是为了提升硬件操作的性能,提升硬件寿命。)

open函数有O_SYNC标志时,write函数会阻塞等待底层完成硬盘写入才返回。这意味着把内容立即写入硬盘中,不需要等待合适的时机。


6、再谈O_APPEND

1)情形1

如果在同一程序中使用两次open函数打开同一个文件,然后分别读取,结果会怎样?

结果可能有两种:一种是fd1和fd2分别读,第二种是接续读。

经过实验验证,证明了结果是fd1和fd2分别读。

结果分析说明:fd1和fd2所对应的文件指针是不同的2个独立的指针。文件指针是包含在动态文件的文件管理表中的,所以可以看出linux系统的进程中不同fd对应的是不同的独立的文件管理表。

2)情形2

如果在同一程序中使用两次open函数打开同一个文件,然后分别写入,结果会怎样?

结果可能有两种:一种是fd1和fd2分别写,第二种是接续读。

经过实验验证,证明了结果是fd1和fd2分别写。(会导致覆盖问题。)

结果分析说明:原因和情形1)一样。另外,正常情况下我们有时候需要分别写,有时候又需要接续写,所以这两种本身是没有好坏之分的,关键看用户需求。

3)如何实现接续写(解决覆盖问题)?

在open时加O_APPEND标志,即可实现接续写,不再出现覆盖问题。

4)O_APPEND的实现原理、原子操作性说明

O_APPEND为什么能够将分别写改为接续写?关键在于文件指针。分别写的内部原理就是2个fd拥有不同的文件指针,并且彼此只考虑自己的位移。但是O_APPEND标志可以让write和read函数内部多做一件事情,就是移动自己文件指针的同时,把别人的文件指针同时移动。虽然加了O_APPEND,fd1和fd2还是各自拥有一个独立的文件指针,但是这两个文件指针关联起来了,一个动了会通知另一个跟着动。

O_APPEND对文件指针的影响,对文件的读写是原子的。整个操作一旦开始就不会被打断,必须等到操作结束后其他代码才能得以调度运行,这就叫原子操作。每种操作系统中都有一些机制来实现原子操作,以保证那些需要原子操作的任务可以运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460628.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle建库及plsql建表空间的用法

所有程序—》ORACLE-JHEMR-----------》配置和移植工具-----》DataBase Configuration Assistant-------中间就需要改一个数据仓库即可,其他的都是下一步,统一口令为**然后建监听服务,测试时改登录为system **,之后用plsql登录上&…

USACO 1.5.4 Checker Challenge

题意:经典的八皇后问题 解法: 采用朴素的每一次放置都与前面的所有行进行比较,在N 13的时候时间会爆掉 《入门经典》上提供的方法很经典,vis数组的使用,具体见《入门经典》125页 /* ID:lsswxr1 PROG:checker LANG:C */…

Spark 1.1.1 Submitting Applications

回到目录 Submitting Applications The spark-submit script in Spark’s bin directory is used to launch applications on a cluster. It can use all of Spark’s supported cluster managersthrough a uniform interface so you don’t have to configure your applicatio…

如何描述变量:存储类、生命周期,作用域、链接属性

可以根据一个变量的存储类、作用域、链接属性、生命周期来描述该变量。 其中,存储类决定了生命周期,作用域决定了链接属性。 存储类 存储类表明变量在哪里存储。见博文Linux下C语言程序的内存布局_天糊土的博客-CSDN博客 作用域 作用域表明变量起作用的…

mysql 修改表名的方法:sql语句

在使用mysql时,经常遇到表名不符合规范或标准,但是表里已经有大量的数据了,如何保留数据,只更改表名呢? 可以通过建一个相同的表结构的表,把原来的数据导入到新表中,但是这样视乎很麻烦。 能否简…

java String类 常用函数

为什么80%的码农都做不了架构师?>>> 1. 获取 int indexOf(int c) int indexOf(int c, int start) char charAt(int index) 2.判断 判断是否包含一个字符串 boolean contains(CharSequence cs) indexOf() //也可以用来判断是否包含 判断是否有内容 boole…

设备驱动程序的简介

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。 一、驱动的概念 设备驱动程序(Device Driver),简称驱动程序、驱动(Driver),指操作系统中用来操控硬件的代码。 驱动是硬件与操…

Android开发实践:掌握Camera的预览方向和拍照方向

Android的Camera相关应用开发中,有一个必须搞清楚的知识点,就是Camera的预览方向和拍照方向,本文就重点讨论一下这个问题。图像的Sensor方向:手机Camera的图像数据都是来自于摄像头硬件的图像传感器(Image Sensor&…

mknod命令:创建设备文件

参考博客:mknod_liangkaiming的博客-CSDN博客 参考资料:man手册 可以通过man 1 mknod查看mknod命令的内容。 1、mknod 命令的作用是make block or character special files,即创建块设备或者字符设备文件。 2、mknod 命令的格式是&#xf…

DreamWeaver使用技巧学习心得

全是我在平时学习网页时积累的,觉得会对遇到同样问题的友人有帮助,都是一些觉得困惑好久然后豁然开朗的心得。 希望大家都能体会到,解决难题后的快乐。 都是我恍然大悟的地方,不够恍然大悟的就不贴上来了。 1.让一个区块居中&…

【转】每天一个linux命令(39):grep 命令

原文网址:http://www.cnblogs.com/peida/archive/2012/12/17/2821195.html Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全…

SecureCRT显示乱码的解决办法

发现问题 在Ubuntu中编写代码,输出语句里带有中文,比如"printf("读出来的内容是:%s.\n", buf);"。使用交叉编译工具链编译后,将可执行程序转移至开发板系统运行,并使用SCRT来观测测试结果。此时发…

WCF数据契约

当使用DataMember时,和访问符无关,及时使用了private,成员都是可见的。相反如果使用static,为不可见。 上述的两个数据成员是等效的,如果是等效的话 数据成员的顺序也必须是相同的。 4.数据契约已知类型——使用KownTy…

Linux中NFS服务器的配置(/etc/export)

本文转载于NFS /etc/exports参数解释,有修改。 问题引入 之前利用NFS从ubuntu中下载根文件系统到开发板(见博客以NFS方式挂载rootfs的设置方法),但只是遵照教程安装的,对里面的设置含义不是很清楚。后来在开发板上上进…

cocos2d 很水很水的看法

这几天接了个扯淡的项目 cocos2d的 。 本来以为是Cpp的, 结果不是2dx ,而是OC的2d。看了几天的官方的dome ,大概知道是什么样子的。我就简单的纪录一下好了: cocos2d的整个框架呢, 分为3层 — 类似舞台剧 演戏嘛 肯定有个boss的 …

详解EBS接口开发之采购申请导入

更多内容可以参考我的博客 详解EBS接口开发之采购订单导入 http://blog.csdn.net/cai_xingyun/article/details/17114697 /*--将数据写入至采购申请接口表*/PROCEDURE insert_procure_main(errbuf OUT NOCOPY VARCHAR2,retcode OUT NOCOPY VARCHAR2)…

sys文件系统

以下内容源于网络资源的学习与整理,如有侵权请告知删除。 前言 Linux2.6版本的内核引入了sys文件系统。 在 proc文件系统介绍和使用 中,介绍了sys文件系统与proc文件系统的差异。它们都是虚拟文件系统,都是内核中的数据结构的可视化接口。它…

spring mvc 配置解析之xml

2019独角兽企业重金招聘Python工程师标准>>> ##mvc.xml中可配置的元素## 既然是xml,当然是要遵循schema的规定. 那么schema文件在哪呢? 定位方法就是解开这个jar文件,找到META-INF/spring.schema文件,这是个文本文件,里面包含了namespace以及其对应的xsd文件的位置…

IOS-UITextField类

文字属性 text placeholder   //默认使用70%灰色 font textColor textAlignment 文字大小 adjustsFontSizeToFitWidth minimumFontSize 编辑行为 editing     //是否正在编辑(read-only) clearsOnBeginEditing 展现形态 borderStyle     //默认UITextBord…

tree命令:以树的形式列出目录中的文件

在linux命令行中,输入“man 1 tree”可以得知tree命令的用法。 这里讲解几个常用的选项。 tree -L level_num :Max display depth of the directory tree. 比如“tree -L 1”,表示深度为1层。 rootubuntu:/sys# ls block bus class de…