思维导图:
一.文件io的概念
文件IO:指程序和文件系统之间的数据交互
特点:
1.不存在缓冲区,访问速度慢
2.不可以移植,依赖于操作系统
3.可以访问不同的文件类型(软连接,块设备等)
4.文件IO属于系统调用
5.文件IO在操作文件时使用文件描述符
二.什么是描述符
当操作一个文件的时候,则需要创建并打开一个文件,系统就会给文件分配一个编号,这个编号就是文件描述符
文件描述符本质就是数组的下表,标准IO是对文件IO的二次封装,所以FILE结构体里面存在文件描述符int _fileno;
1.文件描述符:文件描述符的本质就是数组的下表,默认共有1024个文件描述符,范围[0-1023]
ulimit -a 查看文件描述符的总个数
修改文件描述符的个数(修改只对当前终端有效)
ulimit -n 个数 ---》ulimit -n 2048
2.文件描述符的申请规则:分配从小到大,未申请的文件描述符
举例:申请4个文件,则文件描述符 3 4 5 6,关闭4文件描述符,重新申请则文件描述符是最小的编号4
3.因为文件描述符的个数有限,所以在不适用的情况下,需要关闭
4.查看中的文件描述符的个数函数
三.特殊的文件描述符
stdin--->0
stdout--->1
stderr--->2
四.文件io函数
-
open
功能:打开文件
-
umask
1.什么是umask
umask是文件权掩码
2.查看文件权限掩码umask
umask
3.修改文件权限掩码
1.shell指令(只对当前终端有效)
umask 修改的值 ---->umask 0
2.使用函数实现修改文件权限掩码(只对当前终端有效)
-
close
功能:通过文件描述符关闭文件
-
write
功能:把数据转换为二进制文件,写入到文件中,在文件中以字符的形式展示
-
read
功能:根据文件描述符实现文件读取
-
lseek
功能:文件指针的偏移(修改光标所在位置)
五.获取文件信息
-
stat
功能:获取文件信息(文件类型 文件权限 硬链接数, 用户名 文件所属组, 时间) 不可以获取软链接文件信息,可以使用lstat函数
-
获取文件所属用户 getpwuid
功能:根据用户id获取用户对应的信息
-
获取文件所属组名getgrgid
功能:根据组id,获取组对应的信息
-
获取文件类型和权限
文件类型是由st_mode的高4位决定
权限是由st_mode的第9位决定的
man 7 inode
六.目录相关函数
-
opendir
功能:打开指定路径下目录
-
closedir
功能:关闭目录流指针
-
readdir
功能:读取目录对应的信息
七.练习
- 使用文件IO读取图片 文件大小、文件偏移量,宽度,高度
#include <head1.h>
int main(int argc, const char *argv[])
{int fp=open("xiaoxin.bmp",O_RDONLY);if(fp==-1){PRINT_ERROR("fopen error");return-1;}int bmp_size=0,bmp_width=0,bmp_height=0;lseek(fp,2,SEEK_SET);read(fp,&bmp_size,sizeof(int));printf("图片的大小为:%d字节\n",bmp_size);lseek(fp,18,SEEK_SET);read(fp,&bmp_width,4);read(fp,&bmp_height,4); printf("图像的宽高为:%d * %d\n",bmp_width,bmp_height);close(fp);return 0;
}
运行结果:
2.向一个程序中输入文件名,判断指定目录下是否有这个文件,如果有这个文件,将这个文件的属性信息输出。如果不存在输出不存在即可。
#include <head1.h>
int main(int argc, const char *argv[])
{if (argc != 3) {fprintf(stderr, "使用方法: %s <目录名> <文件名>\n", argv[0]);exit(EXIT_FAILURE);}const char *dir_name = argv[1];const char *file_name = argv[2];DIR *dir = opendir(dir_name);if (dir == NULL) {PRINT_ERROR("无法打开目录");}struct dirent *entry;struct stat file_stat;char file_path[1024];int found = 0;while ((entry = readdir(dir)) != NULL) {if (strcmp(entry->d_name, file_name) == 0) {snprintf(file_path, sizeof(file_path), "%s/%s", dir_name, file_name);if (stat(file_path, &file_stat) == -1) {PRINT_ERROR("获取文件信息失败");}printf("文件存在,属性信息如下:\n");printf("文件路径: %s\n", file_path);printf("文件大小: %ld 字节\n", file_stat.st_size);printf("文件权限: %o\n", file_stat.st_mode & 0777);printf("文件硬链接数: %ld\n", file_stat.st_nlink);struct tm *tm_info = localtime(&file_stat.st_mtime);if (tm_info == NULL){PRINT_ERROR("localtime error");}printf("最后修改的时间:%d-%d-%d %d:%d:%d\n",tm_info->tm_year+1900,tm_info->tm_mon+1,tm_info->tm_mday,tm_info->tm_hour,tm_info->tm_min,tm_info->tm_sec);found = 1;break;}}closedir(dir);if (!found) {printf("文件不存在\n");}return 0;
}