前一段时间看apue的时候 对文件状态标志的操作就比较迷茫 因为是刚开始看, 所以就匆匆的略过了 今天看到高级IO部分,又涉及到这部分问题,所以先要将这个解决才能继续看下去。
首先拿open函数举例
int open(const char *pathname, int oflag, ... );
返回值:成功则返回文件描述符,否则返回 -1
oflag参数所表示的就是文件状态标志所组成的集合,用来说明以什么样的状态打开pathname文件。而此集合是由多个常量的“或”运算构成的 :
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读·写打开
O_APPEND 写时追加
...
create函数可以用来创建一个新文件,open函数通过操作这些状态标志同样也可以达到此目的
create(const char* pathname, mode_t mode);
等价于
open(pathname, O_WRONLY | O_CREATE | O_TRUNC, mode);
该open函数中的oflag参数为三个文件状态标志用或运算组合在一起的
因为没有看过源码起初对这种模式感到很奇怪,谷歌了一下也没有得到满意的答案。
fcnt函数中也存在这类情况
apue中有这样一段代码
//《Unix环境高级编程》程序3-4:打印指定的描述符的文件标志
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int val;
if( argc != 2 )
{
fprintf(stderr, "Usage: a.out <descriptor#>");
exit(1);
}
//改变已打开的文件的性质
val = fcntl( atoi(argv[1]), F_GETFL, 0);
if( val < 0 )
{
fprintf(stderr, "fcntl error for fd %d", atoi(argv[1]));
exit(1);
}
//打印所选择文件的标志说明
switch(val & O_ACCMODE)
{
case O_RDONLY:
printf("Read Only");
break;
case O_WRONLY:
printf("write only");
break;
case O_RDWR:
printf("read write");
break;
default:
fprintf(stderr, "unknow access mode");
exit(1);
}
if( val & O_APPEND )
printf(", append");
if( val & O_NONBLOCK )
printf(", nonblocking");
#if defined(O_SYNC)
if( val & O_SYNC )
printf(", synchronous writes");
#endif
#if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC)
if( val & O_FSYNC )
printf(", synchronous writes");
#endif
putchar('\n');
return 0;
}
或操作
前面提到过文件状态标志就是由一个或多个常量(标志值)组成的
文件状态标志可以用一个二进制数表示 该二进制数的每一位都表示一个常量,二进制数每一位都可以为0或者为1.
为1就表示该常量被选中,为0表示未被选中
举个例子
假设O_WRONLY设为选中的二进制数为 00000001 (即最低位代表O_WRONLY)
假设O_CREATE 设为选中的二进制数为 00000010 (次低位代表 O_CREATE)
假设O_TRUNC 设为选中的二进制数为 00000100 (倒数第三位代表 O_TRUNC)
所以文件状态标志为 O_WRONLY | O_CREATE | O_TRUNC 的二进制表示为 00000111,为上述三个二进制数的或操作
与操作
红色代码处为文件表示状态的与操作 val变量表示的是现有的文件状态标志(可能由一个或多个变量的或操作组成)
假设val 为O_WRONLY | O_APPEND (二进制表示为00001001)
若要看此val中是否包含O_WRONLY? (00001000)
可像红色代码处操作即
if(val &O_WRONLY) 若包含则括号内是一个大于0的数
非操作
ps:
文件标志状态的与或非操作就总结完毕了
红色代码中还有一个 O_ACCMODE 常量 这里就不说明了 google之。