转自:http://book.2cto.com/201212/11767.html 来自《UNIX/Linux程序设计教程》

文件状态标签指明文件的打开属性,它们由open()的flags参数指明(见表3-1)。与描述字标签不同,文件状态标签由与同一次打开文件相连的所有重复文件描述字所共享(参见图3-3)。文件状态标签中的标志可分为三类:访问方式、打开时标志和I/O操作方式。

1. 访问方式

访问方式指明允许文件描述字用于读、写或两者兼之,包括O_RDONLY、O_WRONLY和O_RDWR。这些访问方式在文件被打开时选定,之后便不能再改变。

为了确定文件访问方式,必须从fcntl()取回的文件状态标签中抽取访问方式。因为读和写访问方式不一定是独立的标志位,因此抽取文件访问方式的可移植方法是用宏常数O_ACCMODE位串与文件状态标签值作按位与操作(C中的'&'运算),由此生成表示文件访问方式的值,即O_RDONLY、O_WRONLY或O_RDWR(参见程序3-5)。

2. 打开时标志

打开时标志指明打开文件时影响open()行为的一些选项。这些选项一旦文件打开就不保留,但有一个例外是O_NONBLOCK,因为O_NONBLOCK同时也是一个I/O操作方式,故此标志被保留(3.7节)。

O_CREAT:若设置,当该文件不存在时创建此文件。

O_EXCL:若O_CREAT和O_EXCL同时设置,则当指定的文件已经存在时,open()失败。这保证不会破坏已存在的文件。

O_NONBLOCK:防止open()为打开文件而阻塞很长时间。这通常仅对诸如串行端口的设备文件才有意义。O_NONBLOCK标志同时也作为I/O操作方式标志,这意味着在open()中指明O_NONBLOCK就同时设置了非阻塞I/O方式(3.7节)。为了非阻塞地打开一个文件且不影响正常的阻塞I/O,必须先设置O_NONBLOCK来调用open(),然后调用fcntl()关闭此位。

O_NOCTTY:若命名的文件是终端设备,不让它成为该进程的控制终端(6.9节)。

O_TRUNC:截断文件为零长度,这一选项只对普通文件(4.2.1节)有用,对诸如目录或FIFO之类的特殊文件(4.2.5节)无用。由open()来做截断而不直接调用ftruncate()函数并没有什么太好的理由,只是因为O_TRUNC标志在ftruncate()引入之前就已存在于UNIX中,保留它只是为了向下兼容。

3. I/O操作方式

I/O操作方式影响使用文件描述字进行输入输出操作的工作方式。这些标志由open()设置,之后可以用fcntl()获取和改变。

O_APPEND:文件的附加方式位。若此位设置,所有write()操作写数据至文件尾而不管文件位置在何处。这是附加数据至文件尾唯一可靠的方法。用附加方式可以保证无论是否有其他进程正在写同一个文件,write()操作总是将数据写在当前文件尾。相反,在未设置此位的情况下,如果通过简单地移动文件位置到文件尾,然后再写数据,则在设置文件位置之后开始写之前,可能有其他进程扩展此文件(对应于两个不同的进程打开同一个文件的情形,它们共享同一个vnode,但各自有自己的系统打开文件表,因而有自己的文件位置,参见图3-2),从而导致所写的数据出现在实际文件尾之前的某个地方。

O_NONBLOCK:此标志同时也作为I/O操作方式标志。如果这一位设置,对文件的read()请求,当无立即可用的输入时能以EAGAIN错误状态立即返回,而不是阻塞。类似地,write()请求也能在输出不能写出时以EAGAIN错误状态立即返回。

O_ASYNC:此标志用于信号驱动的I/O(10.2节)。如果这一位设置,当文件描述字中有输入数据时会生成SIGIO信号。

O_SYNC:如果这一位设置,文件按同步I/O方式打开,并将导致任何写该文件的操作都阻塞调用进程直至数据(包括内核I/O缓冲区中的数据)以及与此次写有关的文件属性(4.1.1节)已全部写至物理存储介质(3.9节)。

O_DSYNC:如果这一位设置,文件按同步I/O方式打开,并将导致任何写该文件的操作都阻塞调用进程直至数据(包括内核I/O缓冲区中的数据)已全部已写至物理存储介质(3.9节)。但如果所写的数据不影响读刚写入的数据,则不等待文件属性更新。

O_RSYNC:如果这一位设置,文件按同步I/O方式打开,并将导致任何读该文件的操作都将等待所有写入同一区域的写操作按O_DSYNC和O_SYNC完成后再进行。如果同时设置了O_SYNC 和 O_RSYNC标志,则读操作将阻塞直到文件的访问时间属性已写至物理存储介质。如果同时设置了O_DSYNC 和 O_RSYNC标志,则读操作将阻塞直到所有与保持文件完整性有关的数据都已写至物理存储介质。

简单地说,O_SYNC、O_DSYNC和O_RSYNC这几个标志的主要作用是使数据直接写到磁盘或直接从磁盘读入。

4. 获取和改变文件状态标签

文件状态标签可以用fcntl()函数获取或改变。如下调用:

fcntl (filedes, F_GETFL, new_flags);

获取描述字 filedes的文件状态标签。它的正常返回值是一个非负整数,此数解释为各个独立标志的按位或。因为文件访问方式不是用独立的位表示的,所以,为比较它们需要用O_ACCMODE屏蔽返回值中的其他位。

例3-5 程序3-5是读取文件状态标签的例子,它打印出指定的文件描述字中已设置了的文件状态标签。为了读取文件访问方式标志,我们先用fcntl()返回的标签值val和O_ACCMODE进行“与”操作,然后再比较其结果。而对于其他标志,则直接从val中抽取。

程序3-5 打印文件状态标签函数

#include "cho3.h"

int display_file_status_flages(int fd)

{

int accmode, val;

if ((val = fcntl(fd, F_GETFL, 0) ) < 0)

err_exit("fcntl error");

/* 截取文件访问方式标志 */

accmode = val & O_ACCMODE;

/* 打印出所有设置了的标志 */

if (accmode == O_RDONLY)

printf("read only");

else if (accmode == O_WRONLY)

printf( "write only");

else if (accmode == O_RDWR)

printf("read write");

else {

printf("unknown access mode\n");

exit(1);

}

if (val & O_APPEND)

printf(" , append");

if (val & O_NONBLOCK)

printf(" , nonblocking");

#if !defined(POSIX_SOURCE) && defined(O_SYNC)

if (val&O_SYNC)

printf(", synchronous writes" );

#endif

putchar('\n' );

exit(0);

}

为了设置描述字filedes的文件状态标签,用命令F_SETFL调用fcntl(),该命令要求int类型的第三个参数以指明新标签:

fcntl (filedes, F_SETFL, new_flags);

它的正常返回值是一个非–1的不确定值。–1指出出错。

文件状态标签中,文件的访问方式是在打开文件时设定的,一旦设定便不能改变;打开时标志只在打开时使用,之后便不再保留。因此,应用唯一可以设置的是文件的I/O操作方式,即O_APPEND、O_NONBLOCK。

同设置文件描述字标签类似,如果想修改文件状态标签,同样应当先用F_GETFL调用fcntl()获得当前标签,然后再修改其值。

例3-6 程序3-6给出的函数保证在设置或清除标志O_NONBLOCK 时不会改变其他标签。

程序3-6 设置文件状态标签为非阻塞方式 #include "ch03.h" /* 如果value非0,设置desc的O_NONBLOCK标志,否则清除该标志。成功返回0,失败返回-1 */ int set_nonblock_flag (int desc, int value) {    int oldflags = fcntl(desc, F_GETFL, 0);    if(oldflags == -1)    /* 若获取标签失败,返回错误指示 */        return -1;     /* 形成并设置新标签 */    if(value != 0)        oldflags |= O_NONBLOCK;    else        oldflags &= ~O_NONBLOCK;    return fcntl(desc, F_SETFL, oldflags); }

Linux程序文件状态,linux 文件状态标识和IO操作方式相关推荐

  1. linux程序没有对日志文件写的权限_好程序员云计算培训分享Linux文件权限简单说明...

    好程序员云计算培训分享Linux文件权限简单说明,在 Linux 中的每一个文件或目录都包含有访问权限,这些访问权限决定了谁能访问和如何访问这些文件和目录.通过设定权限可以从以下三种访问方式限制访问权 ...

  2. linux 程序调试日志,Linux程序调试

    Linux下的段错误产生的原因及调试方法 简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址. 一般来说,段错误就是指访问的内存超出了 ...

  3. linux程序设计项目报告,Linux程序设计实验报告大作业

    Linux程序设计实验报告大作业 实 验 报 告 课程名称: LINUX程序设计 学 院: 计算机学院 专 业: 软件工程 班 级: 14-3 姓 名: 张正锟 学 号: 201401061038 2 ...

  4. linux 程序退出 调试,Linux程序调试 - nbspnbspnbspC++nbsp技术中心 - C++博客

    Linux下的段错误产生的原因及调试方法 简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址. 一般来说,段错误就是指访问的内存超出了 ...

  5. linux 程序占内存,linux概念之程序占用内存

    1.在linux下,查看一个运行中的程序,占用了多少内存,一般的命令有 (1). ps aux: 其中  VSZ(或VSS)列 表示,程序占用了多少虚拟内存. RSS列 表示, 程序占用了多少物理内存 ...

  6. 单片机上运行linux程序代码,在Linux下烧录51单片机

    原标题:在Linux下烧录51单片机 *本文作者:LEdge1,本文属 FreeBuf原创奖励计划,未经许可禁止转载. 背景 我一直在学习Linux 系统,但是最近还要学习51单片机,所以在Linux ...

  7. 安卓跑linux程序_Android 运行 Linux 可执行程序

    /**************************************************************************** * Android 运行 Linux 可执行 ...

  8. linux程序压缩运行,linux压缩命令【应对步骤】

    虽然电脑已经很普遍了,但是一些年长的人对电脑的操作不是很熟悉,比如在使用win7系统时一旦遇到linux压缩命令 时就懵了,对于linux压缩命令 处理起来相对来说较简单,按照我们的步骤处理linux ...

  9. linux程序实例获取,Linux命令备忘实例(4)——获取内容

    Linux中的所有内容都是以文件的方式表示的,会有很多需求需要我们获取文件的内容,查看部分或者全部内容.当然最直接方式就是使用编辑器打开文件查看,比如vim.vi.emacs等.这里主要关注的是she ...

最新文章

  1. django创建项目,创建app以及调用templates(模版)和static(静态文件)的方法
  2. Java判断首个或最后字符或者字符串是否为指定的字符/字符串
  3. IDEA中debug
  4. Codeforces 723D. Lakes in Berland
  5. node-media-server win环境安装架测试 踩坑记
  6. spring Autowired(required = false) 说明
  7. 以太坊到底是什么 | 工作原理
  8. [RN] React Native 使用 realm 数据库
  9. 欧几里德算法(求最大公约数和最小公倍数)
  10. spark生成dataframe的几种方式
  11. python支付宝蚂蚁森林_Python教你迅速成为“蚂蚁森林排行榜”第一名
  12. 汇编语言属于计算机科学,汇编语言是一种依赖于计算机的低级程序设计语言吗...
  13. ps计算机图片素材,电脑ps怎么把图片变清晰(手把手教你修图)
  14. linux中apache无法启动,Apache无法启动
  15. 基于Openstack的私有云搭建实践1——概述、原理与整体规划
  16. 09、Flutter FFI Dart Native API
  17. JAVA毕业设计健身房信息管理系统计算机源码+lw文档+系统+调试部署+数据库
  18. 镭速传输攻克视频素材传输顽疾,大幅提升业务效率
  19. Python While循环与break语句_加工零件
  20. 电脑u盘数据丢失怎么恢复 u盘数据无故丢失怎么恢复

热门文章

  1. neo4j的查询语法Cypher+python演示
  2. java使用socket实现一个多线程web服务器
  3. 信息检索:“众筹”专利分析
  4. python聊天机器人
  5. AD小技巧:update changes to PCB后如何调整布线
  6. 华为27asph是什么型号_华为手机原来还有这样神奇的操作?一键了解别人拿你手机做了什么...
  7. [NSUserDefaults]的使用:登陆后不再显示登录界面。
  8. Objective-C 与JAVA的SHA1/HmacSHA1加密算法实现
  9. Week12(11月28日)
  10. layout_weight