LINUX文件操作函数
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;
}
更多推荐


所有评论(0)