2.1.文件读写权限
(1)linux中文件有读写权限,我们在open打开文件时也可以附带一定的权限说明(譬如O_RDONLY就表示以只读方式打开,O_WRONLY表示以只写方式打开,O_RDWR表示以可读可写方式打开);当我们在open文件时附带了某种权限后,打开的文件就只能按照该权限来操作。
2.2.更改文件内容
(1)当我们open已经存在并且内部有内容的文件会出现4种情况(原来的内容消失了(使用O_TRUNC标志);新内容添加在原内容后面(使用O_APPEND标志);新内容添加在原内容前面;不读写该文件时原来该文件的内容不变(默认不使用O_APPEND和O_TRUNC标志));如果O_APPEND和O_TRUNC同时出现,经代码验证O_TRUNC标志起作用,O_APPEND标志作用被屏蔽了。
2.3.退出进程或程序
(1)当程序(进程)在前面的操作执行失败导致后面的操作都不可能进行下去时,我们应在前面的错误监测程序中结束整个程序(进程),不应该让程序(进程)继续运行下去。
(2)在main函数中使用return关键字,一般原则是程序正常终止return 0,程序异常终止return -1,不常用。
(3)正式终止进程(程序)应使用exit或_exit或_Exit之一,一般原则是进程正常终止exit(0),程序异常终止exit(-1),经常使用。
2.4.打开不存在的文件
(1)当我们open某文件时针对该文件是否存在会出现2种情况(创建并且打开并不存在的文件,若该文件存在则该文件会被修改重置(使用O_CREAT标志);创建并且打开并不存在的文件,若该文件存在则会报错,不会创建修改该文件(同时使用O_EXCL标志和O_CREAT标志)) 。
(2)open函数在使用O_CREAT标志去创建文件时,可以使用第3个参数mode来指定要创建的文件的权限;mode使用4个数字来指定权限,其中后面3个很重要,对应我们要创建的目标文件的权限标志;譬如创建1个可读可写不可执行的文件就用0666。
2.5.阻塞与非阻塞
(1)如果某个函数是阻塞式的,则我们调用该函数时当前进程有可能被阻塞住(实质是该函数内部要完成的事情条件不具备,当前没法做,要等待条件成熟),函数被阻塞住了就不能立刻返回;如果某个函数是非阻塞式的,那么我们调用这个函数后一定会立即返回,但是函数有没有完成任务不一定。
(2)阻塞和非阻塞是两种不同的设计思路,并没有好坏;总的来说,阻塞式的结果有保障但是时间没保障;非阻塞式的时间有保障但结果没保障。
(3)操作系统提供的API和由API封装而成的库函数,有很多本身就是被设计为阻塞式或者非阻塞式的,所以我们应用程序调用这些函数的时必须明确该函数是阻塞式还是非阻塞式。
(4)默认情况下,我们open某个文件时是阻塞式的(在打开该文件后读写该文件时若出现问题则会导致阻塞),如果希望以非阻塞的方式打开文件,则flag中要加O_NONBLOCK标志;阻塞与非阻塞只作用于设备文件(linux的硬件设备如串口、I2C通讯器件、LCD),而不作用于普通文件。
2.6.底层阻塞和非阻塞
(1)write默认只是将内容写入底层缓冲区即可返回,然后底层(操作系统中负责实现open、write这些操作的那些代码,也包含OS中读写硬盘等底层硬件的代码)在合适的时候自动会将底层缓冲区中的内容一次性的同步到硬盘中;该设计机制是为了提升硬件操作的性能和硬件寿命;但有时候我们希望硬件不要等待,直接将我们的内容写入硬盘中,则使用O_SYNC标志(write阻塞等待底层完成写入才返回到应用层)。
2.open_exit
/*
* 公司:XXXX
* 作者:Rston
* 博客:http://blog.youkuaiyun.com/rston
* GitHub:https://github.com/rston
* 项目:open函数的flag详解
* 功能:文件读写权限、更改文件内容、退出进程或程序、打开不存在的文件。
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int fd = -1; // fd即file descriptor,文件描述符
int ret = -1; // 用于接收read返回值,判断是否读文件成功
char buf[100] = {0}; // 构建缓冲区存放从文件读出的内容
char bufwrite[20] = "linux is great"; // 构建缓冲区存放要写入文件的内容
// 打开test.txt文件,若该文件不存在则创建(权限666),若该文件存在则报错
fd = open("test.txt", O_RDWR | O_CREAT | O_EXCL, 0666);
if (-1 == fd) // 判断文件打开是否成功,也可这样写if (fd < 0)
{
printf("open file error.\n");
//return -1; // 使用return或exit退出进程或程序
exit(-1);
}
else
{
printf("open file sucess. fd = %d.\n", fd);
}
#if 1
ret = write(fd, bufwrite, strlen(bufwrite)); // 写内容到文件中
if (ret < 0) // 判断内容是否成功写入文件
{
printf("write file errot.\n");
//return -1;
exit(-1);
}
else
{
printf("write %d bytes to file.\n", ret);
printf("the content of write is [%s].\n", bufwrite);
}
#endif
#if 1
ret = read(fd, buf, sizeof(buf)); // 读取文件内容
if (ret < 0) // 判断读取文件是否成功
{
printf("read file error.\n");
//return -1;
exit(-1);
}
else
{
printf("read %d bytes actual from file.\n", ret);
printf("the content of read is [%s].\n", buf);
}
#endif
close(fd); // 关闭文件
//return 0;
exit(0);
}