1.open()

//1.打开已有文件(无需指定权限)
int open(const char *pathname, int flags);
//2.打开/创建文件(创建时必须指定mode权限)
int open(const char *pathname, int flags, mode_t mode);

2.close()

int close(int fd);
成功:返回 0(表示文件描述符已成功释放,内核关闭对应文件句柄);
失败:返回 -1(表示关闭失败,文件描述符可能仍未释放),同时内核会设置全局错误码errno,用于排查失败原因。
perror()
Bad file descriptor 传入无效 fd(如 - 1、已关闭的 fd)
Interrupted system call close 执行时被信号中断(少见)
I/O error 关闭时发生底层 I/O 错误(罕见)

#include <stdio.h>
#include <string.h>
#include <sys/types.h>  // 定义mode_t、dev_t等open依赖的基础数据类型
#include <sys/stat.h>   // 定义文件权限常量(如S_IRUSR)、stat结构体
#include <fcntl.h>      // 声明open函数原型,定义所有打开标志(如O_RDONLY)
#include <unistd.h>  // 声明close()、read()、write()等文件操作函数
#include <errno.h>   // 定义错误码(如ENOENT文件不存在)
#include <stdio.h>   // 配合perror()打印直观的错误信息

void main(int argc, const char *argv[])
{
    //第一个参数 不写路径默认当前路径下文件
    //第二个参数 文件不存在则创建新文件
    //创建新文件需要第三个参数,默认权限0666
    if(argc != 2)
    {
        printf("参数输入错误!\n");
        printf("usage: a.out <dst_file>\n");
        return -1;
    }
    int fd;
    //文件不存在创建文件,文件存在报错;
    fd = open(argv[1], O_RDONLY|O_CREAT|O_EXCL, 0666);
    if(fd == -1)
    {
        perror("文件打开失败!");
        // printf("errno:%d\n", errno);
        if(errno == EEXIST)
        {
            printf("文件已存在!\n");
        }
        return -1;
    }
    printf("文件打开成功!\n");
    int close_fd;

    close_fd = close(fd);
    if(close_fd == -1)
    {
        printf("文件关闭失败!\n");
        return -1;
    }
    return 0;
}


3.read()

ssize_t read(int fd, void *buf, size_t count);
返回值
n > 0 成功读取n个字节(n ≤ count) 继续处理缓冲区中的n个字节数据(注意:不一定能读到 count 个字节)
n = 0 到达文件末尾(EOF),无数据可读 停止读取,关闭文件描述符
n = -1 读取失败 检查errno判断失败原因,分情况处理

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>   
#include <unistd.h>   // 包含close函数原型
#include <errno.h>    //errno函数原型

void main(int argc, const char *argv[])
{
    //第一个参数 不写路径默认当前路径下文件
    //第二个参数 文件不存在则创建新文件
    //创建新文件需要第三个参数,默认权限0666
    if(argc != 2)
    {
        printf("参数输入错误!\n");
        printf("usage: a.out <dst_file>\n");
        return -1;
    }
    int fd;
    //文件不存在创建文件,文件存在报错;
    fd = open(argv[1], O_RDONLY);
    if(fd == -1)
    {
        perror("文件打开失败!");
        // printf("errno:%d\n", errno);
        if(errno == EEXIST)
        {
            printf("文件已存在!\n");
        }
        return -1;
    }
    printf("文件打开成功,文件描述符%d\n", fd);
    //读取文件数据
    char read_buf[1024] = {0};
    int readback_date = 0;
    readback_date = read(fd, read_buf, sizeof(read_buf));
    if(fd == -1)
    {
        perror("文件读取失败!\n");
        return -1;
    }
    printf("文件读取成功\n");
    printf("%s\n", read_buf);


    close(fd);
    return 0;
}

4.write()

ssize_t write(int fd, const void *buf, size_t count);
fd int 有效文件描述符(open/creat返回的非负整数),必须是可写模式打开(O_WRONLY/O_RDWR/O_APPEND)
buf const void * 存储待写入数据的内存缓冲区指针,const表示 write 不会修改缓冲区内容,不能是 NULL
count size_t 期望写入的字节数(非负整数),通常设为缓冲区中有效数据的长度(如字符串用 strlen (buf))

#include <sys/types.h>   // open依赖的基础数据类型
#include <sys/stat.h>    // open依赖的权限常量
#include <fcntl.h>       // open函数声明、打开标志(如O_WRONLY/O_APPEND)
#include <errno.h>       // 定义错误码,排查write失败原因
#include <stdio.h>       // 配合perror()打印直观的错误信息
#include <string.h>      // 可选,用于strlen()计算字符串长度
#include <stdio.h>
#include <string.h>
#include <unistd.h>   // 包含close函数原型


void main(int argc, const char *argv[])
{
    //第一个参数 不写路径默认当前路径下文件
    //第二个参数 文件不存在则创建新文件
    //创建新文件需要第三个参数,默认权限0666
    if(argc != 2)
    {
        printf("参数输入错误!\n");
        printf("usage: a.out <dst_file>\n");
        return -1;
    }
    int fd;
    ssize_t ret_wr = 0;
    struct student
    {
        char name[10];
    };

    //读写方式打开文件
    //文件不存在创建文件,文件存在报错;
    //文件存在则清空文件内容
    fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);
    if(fd == -1)
    {
        perror("文件打开失败!");
        return -1;
    }
    printf("文件打开成功,文件描述符%d\n", fd);
    //向文件写入数据
    int value = 100;
    char str_buf[] = "hello book!";
    //写入整数
    // ret_wr = write(fd, &value, sizeof(value));
    // if(ret_wr == -1)
    // {
    //     perror("写入失败:");
    //     return -1;
    // }
    // printf("整数写入成功!\n");

    //写入字符串
    // ret_wr = write(fd, str_buf, strlen(str_buf));
    // if(ret_wr == -1)
    // {
    //     perror("写入失败:");
    //     return -1;
    // }
    //printf("字符串写入成功!\n");

    //写入结构体
    struct student stu = {"张三22"};
    ret_wr = write(fd, &stu, sizeof(str_buf));
    if(ret_wr == -1)
    {
        perror("写入失败:");
        return -1;
    }
    printf("结构体写入成功!\n");

    //读取文件数据
    // char read_buf[1024] = {0};
    // int readback_date = 0;
    // readback_date = read(fd, read_buf, sizeof(read_buf));
    // if(fd == -1)
    // {
    //     perror("文件读取失败!\n");
    //     return -1;
    // }
    // printf("文件读取成功\n");
    // printf("%s\n", read_buf);

    close(fd);
    return 0;
}



5.fcntl()

int fcntl(int fd, int cmd, … /* arg */ );
fcntl(file control)的作用是对已打开的文件描述符进行各种控制操作
参数:
fd:需要操作的文件描述符(如 open() 返回的整数)。
cmd:操作命令(核心参数,决定要执行的操作类型)。
…:可选参数,类型和含义由 cmd 决定(多数场景下是 int 或 struct flock 类型)。
返回值:
成功:根据 cmd 不同返回不同值(如获取标志时返回标志值,设置操作时返回 0)。
失败:返回 -1,并设置 errno 提示错误原因(如 EBADF 表示文件描述符无效)。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>   
#include <unistd.h>   // 包含close函数原型
#include <errno.h>    //errno函数原型

void main(int argc, const char *argv[])
{
    //判断参数
    if(argc != 2)
    {
        printf("参数输入错误!\n");
        printf("usage: a.out <dst_file>\n");
        return -1;
    }
    //打开文件
    int op_fd;
    op_fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);
    if(op_fd == -1)
    {
        perror("文件打开失败!");
        return -1;
    }
    printf("文件打开成功!\n");
    //给文件加锁
    //定义一个锁的结构体
    struct flock file_lock;
    //写内容,写锁
    file_lock.l_type = F_WRLCK;
    //基准位置 文件开头
    file_lock.l_whence = SEEK_SET;
    //起始位置 从文件开头加锁
    file_lock.l_start = 0;
    //加锁长度 0加到末尾
    file_lock.l_len = 0;
    if(-1 == fcntl(op_fd, F_SETLK, &file_lock))
    {
        perror("文件加锁失败!");
        return -1;
    }
    printf("文件加锁成功!\n");
    //写入内容
    char *str = "hello world!";
    if(-1 == write(op_fd, str, strlen(str)))
    {
        perror("写入失败");
        return -1;
    }
    printf("写入成功\n");
    //给文件解锁
    file_lock.l_type = F_UNLCK;
    if(-1 == fcntl(op_fd, F_UNLCK, &file_lock))
    {
        perror("解锁失败!");
        return -1;
    }
    printf("文件解锁成功!\n");
    //关闭文件
    close(op_fd);
}

6.stat()

头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
函数
int stat(const char *pathname, struct stat *statbuf);
作用:
stat() 函数的作用是获取指定路径文件的元数据(比如文件大小、权限、创建 / 修改时间、文件类型等),并将这些信息填充到一个 struct stat 结构体中。
参数:
pathname:要查询的文件路径(绝对 / 相对路径)。
statbuf:指向 struct stat 结构体的指针,用于存储文件状态信息。
返回值:
成功:返回 0;
失败:返回 -1,并设置 errno(比如文件不存在时 errno=ENOENT)。

//核心结构体
struct stat {
    dev_t     st_dev;         // 文件所在设备的ID
    ino_t     st_ino;         // 索引节点号(inode)
    mode_t    st_mode;        // 文件类型和权限(核心)
    nlink_t   st_nlink;       // 硬链接数
    uid_t     st_uid;         // 文件所有者的UID
    gid_t     st_gid;         // 文件所属组的GID
    dev_t     st_rdev;        // 设备文件的设备ID(仅特殊文件有效)
    off_t     st_size;        // 文件大小(字节,普通文件有效)
    blksize_t st_blksize;     // 文件系统的块大小
    blkcnt_t  st_blocks;      // 占用的磁盘块数
    time_t    st_atime;       // 最后访问时间(access time)
    time_t    st_mtime;       // 最后修改时间(modify time,内容修改)
    time_t    st_ctime;       // 最后状态改变时间(change time,元数据修改)
};
//代码示例
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>   
#include <unistd.h>   // 包含close函数原型
#include <errno.h>    //errno函数原型

// 用户权限 (User)
#define U_R 0400  // 用户读权限 000 100 000 000
#define U_W 0200  // 用户写权限 000 010 000 000
#define U_X 0100  // 用户执行权限 000 001 000 000
#define U_RWX 0700 // 用户读写执行权限 000 111 000 000 (U_R | U_W | U_X)
#define U_RW 0600  // 用户读写权限 000 110 000 000 (U_R | U_W)
#define U_RX 0500  // 用户读执行权限 000 101 000 000 (U_R | U_X)
#define U_WX 0300  // 用户写执行权限 000 011 000 000 (U_W | U_X)

// 组权限 (Group)
#define G_R 0040  // 组读权限 000 000 100 000
#define G_W 0020  // 组写权限 000 000 010 000
#define G_X 0010  // 组执行权限 000 000 001 000
#define G_RWX 0070 // 组读写执行权限 000 000 111 000 (G_R | G_W | G_X)
#define G_RW 0060  // 组读写权限 000 000 110 000 (G_R | G_W)
#define G_RX 0050  // 组读执行权限 000 000 101 000 (G_R | G_X)
#define G_WX 0030  // 组写执行权限 000 000 011 000 (G_W | G_X)

#define O_R 0004  // 其他用户读权限 000 000 000 100
#define O_W 0002  // 其他用户写权限 000 000 000 010
#define O_X 0001  // 其他用户执行权限 000 000 000 001

void main(int argc, const char *argv[])
{
    //判断参数
    if(argc != 2)
    {
        printf("参数输入错误!\n");
        printf("usage: a.out <dst_file>\n");
        return -1;
    }

    struct stat fileDataStruct;
    int ret_stat;
    //使用stat函数求文件属性 链接文件获取到的事目标文件的属性
    if(-1 == (ret_stat == stat(argv[1], &fileDataStruct)))
    {
        perror("文件属性读取失败!");
        return -1;
    }
    printf("文件属性读取成功! %d \n", ret_stat);
    //文件类型
    //文件权限
    //文件大小
    switch(fileDataStruct.st_mode&__S_IFMT)
    {
        case __S_IFREG:
            printf("-");
            break;
        case __S_IFDIR:
        printf("d");
            break;
        case __S_IFLNK:
            printf("l");
            break;
        default:
            printf("其他类型文件");
            break;
    }

    //求用户的权限
    printf("%c", (fileDataStruct.st_mode&U_R)?'r':'-');
    printf("%c", (fileDataStruct.st_mode&U_W)?'w':'-');
    printf("%c", (fileDataStruct.st_mode&U_X)?'x':'-');

    printf("%c", (fileDataStruct.st_mode&G_R)?'r':'-');
    printf("%c", (fileDataStruct.st_mode&G_W)?'w':'-');
    printf("%c", (fileDataStruct.st_mode&G_X)?'x':'-');

    printf("%c", (fileDataStruct.st_mode&O_R)?'r':'-');
    printf("%c", (fileDataStruct.st_mode&O_W)?'w':'-');
    printf("%c", (fileDataStruct.st_mode&O_X)?'x':'-');
    //文件权限 8进制
    printf("%o", (fileDataStruct.st_mode&0777));


    printf("\n");
    return 0;
    // //关闭文件
    // close(op_fd);
}

7.getpwuid()

getpwuid() 是 POSIX 标准库中的函数,定义在 <pwd.h> 头文件中,核心作用是通过用户 ID(UID) 查询系统的用户数据库(通常是 /etc/passwd 文件),返回包含该用户所有信息的结构体。
struct passwd *getpwuid(uid_t uid);
头文件:
#include <sys/types.h>
#include <pwd.h>
返回值:
getpwuid() 返回的结构体指针指向静态内存,后续调用(如 getpwnam())会覆盖该内存,不要长期持有;
函数失败时,pw_info 为 NULL:

//结构体内容
struct passwd {
    char   *pw_name;    // 用户名(如 root、testuser)
    char   *pw_passwd;  // 密码占位符(通常是 'x',真实密码存在 /etc/shadow)
    uid_t   pw_uid;     // 用户ID(数字,如 root 是 0)
    gid_t   pw_gid;     // 组ID(数字)
    char   *pw_gecos;   // 用户注释/描述信息
    char   *pw_dir;     // 用户主目录(如 /home/testuser)
    char   *pw_shell;   // 默认登录shell(如 /bin/bash)
};


#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>   
#include <unistd.h>   // 包含close函数原型
#include <errno.h>    //errno函数原型
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>   
#include <unistd.h>   // 包含close函数原型
#include <errno.h>    //errno函数原型
#include <dirent.h>
#include <pwd.h>

void main(int argc, const char *argv[])
{
    //判断参数
    // if(argc != 2)
    // {
    //     printf("参数输入错误!\n");
    //     printf("usage: a.out <dst_file>\n");
    //     return -1;
    // }
    struct passwd *getpwuid(uid_t uid);
    //根据UID获取用户信息结构体
    uid_t uid_get = 1000;
    struct passwd *pw = NULL;
    pw = getpwuid(uid_get);
    if(pw == NULL)
    {
        perror("获取uid失败!");
        return -1;
    }
    printf("获取uid成功!\n");
    //访问结构体成员 用户名 是否有密码 用户uid 组gid  
    printf("用户名:%s\n", pw->pw_name);
    printf("密码:%s\n", pw->pw_passwd);
    printf("UID:%d\n", pw->pw_uid);
    printf("GID:%d\n", pw->pw_gid);


    
    return 0;
}


8.getgrgid()

getgrgid() 是 POSIX 标准库函数,定义在 <grp.h> 头文件中,核心作用是查询系统的组数据库(通常是 /etc/group 文件),根据组 ID(GID) 返回该组的所有信息。
struct group *getgrgid(gid_t gid);
头文件:
#include <sys/types.h>
#include <grp.h>

struct group {
    char   *gr_name;    // 组名(如 root、wheel、testgroup)
    char   *gr_passwd;  // 组密码占位符(通常是 'x',真实密码在 /etc/gshadow)
    gid_t   gr_gid;     // 组ID(数字,如 root 组是 0)
    char  **gr_mem;     // 组成员列表(字符串数组,以 NULL 结尾)
};
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>   
#include <unistd.h>   // 包含close函数原型
#include <errno.h>    //errno函数原型
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>   
#include <unistd.h>   // 包含close函数原型
#include <errno.h>    //errno函数原型
#include <dirent.h>
#include <pwd.h>
#include <grp.h>

void main(int argc, const char *argv[])
{
    //判断参数
    // if(argc != 2)
    // {
    //     printf("参数输入错误!\n");
    //     printf("usage: a.out <dst_file>\n");
    //     return -1;
    // }
    struct passwd *getpwuid(uid_t uid);
    //根据UID获取用户信息结构体
    uid_t grgid_get = 116;
    struct group *gr = NULL;
    
    gr = getgrgid(grgid_get);
    if(gr == NULL)
    {
        perror("获取gid失败!");
        return -1;
    }
    printf("获取gid成功!\n");
    //访问结构体成员 用户名 是否有密码 用户uid 组gid  
    printf("用户名:%s\n", gr->gr_name);
    printf("密码:%s\n", gr->gr_passwd);
    // printf("member:%d\n", gr->gr_mem);
    printf("GID:%d\n", gr->gr_gid);
    for (int i = 0; gr->gr_mem[i]; i++)
    {
        /* code */
        printf("%s\n", gr->gr_mem[i]);
    }
    

    
    return 0;
}

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐