2.open函数的flag详解

本文详细介绍了Linux中open函数的权限使用,包括读写权限、文件内容更改、O_TRUNC和O_APPEND标志的影响。此外,讨论了程序在遇到错误时的退出策略,以及如何创建新文件,特别是O_CREAT和O_EXCL标志的作用。文章还探讨了阻塞和非阻塞模式,指出默认open函数是阻塞式的,通过O_NONBLOCK标志可以设置为非阻塞,并解释了O_SYNC标志在确保数据同步到硬盘上的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值