首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Linux环境下的open函数分析(一)

Linux环境下的open函数分析(一)

作者头像
用户6280468
发布2022-03-18 15:21:12
发布2022-03-18 15:21:12
1.9K0
举报
文章被收录于专栏:txp玩Linuxtxp玩Linux

-----今天晚上醍醐灌顶,听了一些大神前辈的指导,受益匪浅。哈哈,还是写文章吧,明天还是要搬砖呢。 今天分享的是linux环境下open函数的解析,其实在前面的文章里面我只是简单的用了一下open函数的用法(因为自己也是刚开始在学习linux,不是很懂,大神勿喷,还请多指出不足之处),当然它还有好多用法和需要注意的地方。说到这里我又想起了man手册,哈哈,因为它可以在linux环境下查看命令和api以及库函数的具体用法,实在是太强悍了。只是注解是英文的(当然也可以安装系统的时候搞成中文的,但是中文有的时候翻译的不准确,有些词语不好理解,往往英文会更好理解,前提是要一定的英文水平,不然会很难静下心来看完),就如下面,我用 man 2 open 来查看:

全是英文,哈哈,其实不要怕,我挑重点来讲,下面来看分析: 一、文件的权限:

代码语言:javascript
复制
   int open(const char *pathname, int flags);
   int open(const char *pathname, int flags, mode_t mode);
 The  argument  flags  must  include one of the following access modes:
   O_RDONLY, O_WRONLY, or O_RDWR.  These request opening the  file  read-
   only, write-only, or read/write, respectively.

上面是原注释,我们可以看到:open函数里面的参数flag是表示文件打开是什么方式来打开的(也就是说权限,打开文件的时候,权限设置是只读权限,后面你再对文件写操作的话,系统是不允许这样做的),这里我们可以看到在打开文件的时候,有三种权限设置: 1)O_RDONLY:表示只读,也就是文件只能读,不能写入 2)O_RDWR:表示既可以读又可以写 3)O_WRONLY:表示只能写操作,不能进行读操作 注:这里操作比较简单,我就没有用代码来举例子了。 二、O_APPEND和O_TRUNC的使用: 1、老样子,我们还是先看原注释是怎么注释的:

代码语言:javascript
复制
 O_APPEND

          The file is opened in append mode.  Before each  write(2),  the
          file  offset  is  positioned at the end of the file, as if with
          lseek(2).  The modification of the file offset  and  the  write
          operation are performed as a single atomic step.
           O_APPEND may lead to corrupted files on NFS filesystems if more
          than one process appends data to  a  file  at  once.   This  is
          because NFS does not support appending to a file, so the client
          kernel has to simulate it, which can't be done without  a  race
          condition.

       O_TRUNC
          If the file already exists and is a regular file and the access
          mode allows writing (i.e., is O_RDWR or O_WRONLY)  it  will  be
          truncated  to  length  0.   If  the  file is a FIFO or terminal
          device file, the  O_TRUNC  flag  is  ignored.   Otherwise,  the
          effect of O_TRUNC is unspecified.

从上面我们可以大概看出O_APPEND和O_TRUNC的用法了,大概是: a、O_TRUNC属性去打开文件时,如果这个文件中本来是有内容的,则原来的内容会被丢弃。 b、O_APPEND属性去打开文件时,如果这个文件中本来是有内容的,则新写入的内容会在原来的内容后面添加 注:exit _exit _Exit都可以表示退出进程 2、我们来用代码来演示一下O_APPEND的用法:

代码语言:javascript
复制
 root@ubuntu-virtual-machine:/mnt/hgfs/day# ls
 a.out  a.txt  file  file1.c  linux
 root@ubuntu-virtual-machine:/mnt/hgfs/day# cat a.txt
 l love linuxroot@ubuntu-virtual-machine:/mnt/hgfs/day# 

注:我在day目录下创建一个a.txt的文本文件,内容是 I love linux,现在通过使用O_APPEND,看看能实现什么效果,代码如下:

代码语言:javascript
复制
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
 int main(int argc, char *argv[])
 {
    int fd = -1;            // fd 就是file descriptor,文件描述符
    char buf[100] = {0};
    char writebuf[20] = "l love mcu";
    int ret = -1;
    // 第一步:打开文件
    fd = open("a.txt", O_RDWR | O_APPEND );
    if (-1 == fd)           // 有时候也写成: (fd < 0)
    {
            printf("文件打开错误\n");
            // return -1;
            _exit(-1);
    }
    else
    {
            printf("文件打开成功,fd = %d.\n", fd);
    }
    // 第二步:读写文件
    // 写文件
   ret = write(fd, writebuf, strlen(writebuf));
    if (ret < 0)
    {
            printf("write失败.\n");
            _exit(-1);
    }
    else
    {
            printf("write成功,写入了%d个字符\n", ret);
    }
    close(fd);
    _exit(0);

} 最终的效果是a.txt文本文件末尾添加了"I love mcu":

3)O_TRUNC的用法:

代码语言:javascript
复制
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
 int main(int argc, char *argv[])
 {

    int fd = -1;            // fd 就是file descriptor,文件描述符
    char buf[100] = {0};
    char writebuf[20] = "l love mcu";
    int ret = -1;
    // 第一步:打开文件
    fd = open("a.txt", O_RDWR | O_TRUNC );
    if (-1 == fd)           // 有时候也写成: (fd < 0)
    {
            printf("文件打开错误\n");
            // return -1;
            _exit(-1);
    }
    else
    {
            printf("文件打开成功,fd = %d.\n", fd);
    }
    // 第二步:读写文件
   // 写文件
    ret = write(fd, writebuf, strlen(writebuf));//write函数的用法也可以用man手册来查看的
    if (ret < 0)
    {
            printf("write失败.\n");
            _exit(-1);
    }
    else
    {
            printf("write成功,写入了%d个字符\n", ret);
    }
    close(fd);
    _exit(0);
}

效果是,使用O_TRUNC模式时,a.txt文本文件里面的内容被删除掉了:

4)如果O_APPEND和O_TRUNC同时使用:

代码语言:javascript
复制

 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
 int main(int argc, char *argv[])
 {
    int fd = -1;            // fd 就是file descriptor,文件描述符
    char buf[100] = {0};
    char writebuf[20] = "hhhhohohohoh";
    int ret = -1;
    // 第一步:打开文件
    fd = open("a.txt", O_RDWR | O_TRUNC|O_APPEND );
    if (-1 == fd)           // 有时候也写成: (fd < 0)
    {
            printf("文件打开错误\n");
            // return -1;
            _exit(-1);
    }
    else
    {
            printf("文件打开成功,fd = %d.\n", fd);
    }
    // 第二步:读写文件
 // 写文件
    ret = write(fd, writebuf, strlen(writebuf));
    if (ret < 0)
    {
            printf("write失败.\n");
            _exit(-1);
    }
    else
    {
            printf("write成功,写入了%d个字符\n", ret);
    }
    close(fd);
    _exit(0);
}

结果是,a.txt原来在使用O_TRUNC的时候留下内容,在同时使用了O_APPEND和O_TRUNC后,原来的内容被替换掉了,用法和单独用O_TRUNC 一样:

三、总结:

通过用man手册来查看一个陌生函数的用法,这是非常好的一个学习方法今天的分享就到这里了,明天继续分享,记得关注我哦!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 txp玩Linux 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档