Linux open/openat/creat/lseek 函数

一、头文件以及声明

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

// 打开文件
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

// 创建文件
int creat(const char *pathname, mode_t mode);

//在某个文件夹内打开文件(传入文件夹的文件描述符)
int openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);


#include <sys/types.h>
#include <unistd.h>
// 移动文件操作指针位置
off_t lseek(int fd, off_t offset, int whence);

// whence可选值
// SEEK_SET 从文件头
// SEEK_CUR 从当前指针位置 (可正可负)
// SEEK_END 从文件尾部 (可正可负)

参考:https://www.man7.org/linux/man-pages/man2/open.2.html

二、说明

返回值: 文件描述符 【标识着文件的资源id,仅相对打开该文件的进程有效)】

flags常用可选值:

  • O_APPEND 追加写入:打开文件后,文件操作指针指向文件尾部
  • O_RDONLY 只读打开
  • O_WRONLY 只写打开
  • O_CREAT 如果文件不存在时,创建该文件使用了O_CREAT参数时,必须指定mode_t
  • O_RDWR 可读可写打开
  • O_DIRECTORY 以文件夹方式打开,如果不是文件夹则打开失败
  • O_DSYNC
  • O_SYNC
  • O_TRUNC 打开文件时会清空文件内容(立即生效于文件)
    更多请查阅文档

mode_t 只有flags为O_CREAT时有效可选值:

  • 文件所有者权限配置
  • S_IRWXU 00700 user (file owner) has read, write, and execute permission
  • S_IRUSR 00400 user has read permission
  • S_IWUSR 00200 user has write permission
  • S_IXUSR 00100 user has execute permission
  • 文件所有者所在组权限配置
  • S_IRWXG 00070 group has read, write, and execute permission
  • S_IRGRP 00040 group has read permission
  • S_IWGRP 00020 group has write permission
  • S_IXGRP 00010 group has execute permission
  • 其他用户权限配置
  • S_IRWXO 00007 others have read, write, and execute permission
  • S_IROTH 00004 others have read permission
  • S_IWOTH 00002 others have write permission
  • S_IWOTH 00002 others have write permission
  • S_IXOTH 00001 others have execute permission
  • According to POSIX, the effect when other bits are set in mode
    is unspecified. On Linux, the following bits are also honored
    in mode:
    • S_ISUID 0004000 set-user-ID bit
    • S_ISGID 0002000 set-group-ID bit (see inode(7)).
    • S_ISVTX 0001000 sticky bit (see inode(7)).

三、实例

运行环境:Ubuntu 20.04 LTS

3.1 open函数 O_TRUNC(包含O_CREAT)实例
#include <stdio.h>
// open/openat/creat
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// read/write
#include <unistd.h>

#include <string.h>
#include <stdlib.h>


int main(int argc, char *args)
{
    int fd = -1;
    // open with trunc 不存在时创建
    fd = open("trunc", O_TRUNC|O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
    // open运行之后,文件内容会立即被清空
    if (fd < 0) {
        perror("open(O_TRUNC) file with error");
        exit(-1);
    }
    write(fd, "test", strlen("test"));
    close(fd);
    return 0;
}
3.2 open函数 O_DIRECTORY实例
#include <stdio.h>
// open/openat/creat
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// read/write
#include <unistd.h>

#include <string.h>
#include <stdlib.h>


int main(int argc, char *args)
{
    int fd_dir = -1;
    // open the "test_dir" directory
    fd_dir = open("test_dir", __O_DIRECTORY);
    printf("open fd_dir: %d\n", fd);
    if (fd_dir < 0) {
        perror("open dir with error");
        exit(-1);
    }
    close(fd_dir);
    return 0;
}
3.3 creat函数实例
#include <stdio.h>
// open/openat/creat
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// read/write
#include <unistd.h>

#include <string.h>
#include <stdlib.h>


int main(int argc, char *args)
{
    // creat hotice0 directory
    close(creat("hotice0", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP));
    return 0;
}
3.4 openat 函数实例
#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 *args)
{
    int fd = -1;
    int fd_dir = -1;
    const char *str_buf = "test content\nhotice0";
    ssize_t str_len = strlen(str_buf);
    ssize_t ret_len = -1;
    
    // open the "test_dir" directory【运行前请创建该文件夹】
    fd_dir = open("test_dir", __O_DIRECTORY);
    printf("open fd_dir: %d\n", fd);
    if (fd_dir < 0) {
        perror("open dir with error");
        exit(-1);
    }
    
    // openat: open the test on test_dir 【在test_dir文件夹内打开test文件(不存在时创建)】
    fd = openat(fd_dir, "test", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
    printf("openat fd: %d\n", fd);
    if (fd < 0) {
        perror("openat file with error");
        exit(-1);
    }
    ret_len = write(fd, str_buf, str_len);
    if (ret_len != str_len) {
        perror("write file with error");
        exit(-1);
    }
    close(fd);
    close(fd_dir);
    return 0;
}
3.5 lseek 函数实例
#include <stdio.h>
// open/openat/creat
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// read/write/lseek
#include <unistd.h>

#include <string.h>
#include <stdlib.h>


int main(int argc, char *args)
{
    int fd = -1;
    ssize_t ret_len = -1;
    int i = 0;
    fd = open("test", O_TRUNC|O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
    if (fd < 0) {
        perror("open file with error");
        exit(-1);
    }

    for (i = 0; i < 4; i++) {
        lseek(fd, i, SEEK_SET);
        write(fd, "w", 1); // w -> 0x77
    }

    lseek(fd, 5, SEEK_CUR);
    write(fd, "end", 3);// end -> 0x 65 6e 64
    

    close(fd);
    return 0;
}

文件最终的内容用hexdump打印出来如下

hotice0@ubuntu:~/Documents/Unix_Program$ hexdump test
0000000 7777 7777 0000 0000 6500 646e
000000c

备注:end的16进制是65 6e 64

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
open函数openat函数都是用于打开文件的系统调用,但它们有一些区别。 1. 参数传递方式: - open函数接受一个文件路径名作为参数,该路径名可以是绝对路径或相对路径。 - openat函数需要传递一个已打开的目录文件描述符(dirfd)和一个相对于该目录的路径名作为参数。这种方式可以更加灵活地控制文件的打开位置。 2. 目录解析方式: - open函数的文件路径名会根据当前进程的工作目录进行解析。 - openat函数的路径名是相对于提供的目录文件描述符(dirfd)进行解析。 3. 安全性考虑: - open函数在解析文件路径时,依赖于进程的当前工作目录。这可能会导致安全性问题,特别是在多线程环境下,因为当前工作目录是共享的。 - openat函数提供了更安全的方式,可以避免依赖于进程的当前工作目录,而是通过提供目录文件描述符来指定相对路径。 使用示例: 以下是使用open函数openat函数打开文件的示例代码: 使用open函数打开文件: ```c #include <fcntl.h> int fd = open("/path/to/file", O_RDWR); if (fd == -1) { // 打开文件失败 } // 在文件中进行读写操作 ``` 使用openat函数打开文件: ```c #include <fcntl.h> #include <unistd.h> int dirfd = open("/path/to/directory", O_RDONLY); if (dirfd == -1) { // 打开目录失败 } int fd = openat(dirfd, "file.txt", O_RDONLY); if (fd == -1) { // 打开文件失败 } // 在文件中进行读操作 close(fd); close(dirfd); ``` 需要注意的是,使用完打开的文件描述符后,需要调用close函数关闭文件描述符,以释放资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值