目录
文件io就是对文件的打开、读写、关闭等的一些列操作
文件IO分为两类 1.标准文件IO---》标准C库给我提供一套针对文件操作的一系列库函数---》标准文件IO存在缓存区 2.系统文件IO---》Linux操作系统自带一套针对文件操作的一系列系统调用---》系统文件IO没有缓存区 有缓存是好事,减少了访问系统的次数,减少系统开销。
1.标准文件io缓存
1.1全缓存
#include <stdio.h>
int main(int argc, const char *argv[])
{
while(1)
{
printf("Hello world!!");//注意此处不加\n
sleep(1);
}
return 0;
}
//全缓存 要经过缓存区 缓存区满了一次性打印终端上
//总结: 标准文件IO 存在缓存区 缓存区默认是1024
1.2行缓存
#include <stdio.h>
int main(int argc, const char *argv[])
{
while(1)
{
printf("Hello world!!\n");//注意此处加\n
sleep(1);
}
return 0;
}
//总结:加\n不经过缓存区 直接将内容输出终端
2.标准文件io操作函数
2.1 fopen函数
fopen
(1)功能:打开文件--》在1程序中将文件打开
(2)头文件及函数原型
#include<stdio.h>
FILE *fopen(const char *path, const char *mode);
(3)参数说明
const char *path //要打开文件的路径+文件名 /home/linux/namelist.txt
const char *mode //打开文件的模式
//"r" 只读
//"r+" 可读可写
//"w" 只写 如果文件不存在会新建,存在清空
//"w+" 可读可写 如果文件不存在会新建,存在清空
//"a" 只写 如果文件不存在会新建,存在不清空追加写入
//"a+" 可读可写 如果文件不存在会新建,存在不清空追加写入
read //读
write//写
append //追加
(4)返回值 FILE*---->结构体指针 ---》文件流指针
每当我们在程序中打开一个文件,系统就会在内核空间开辟一块地方存储文件相关的内容。
将内核空间的首地址返回FILE*
成功:返回的内核空间存放该文件首地址
失败:返回NULL
2.2 fclose函数
fclose //file close
(1)功能:关闭文件 ---》关闭文件之前会刷新输入输出缓存区,然后在释放内核空间。
(2)头文件及函数原型
#include <stdio.h>
int fclose(FILE *fp);
(3)参数说明:
FILE *fp //fopen的返回值
(4)返回值
成功:
返回 0
失败:
返回 -1
//调用参考
fclose(fp);
2.2.1 fopen和fclose案例代码
#include <stdio.h>
int main(int argc, const char *argv[])
{
//1.以可读可写的方式打开文件
FILE *fp = fopen("./test1.c", "r+");
if(fp == NULL)//如果返回值是NULL,说明打开失败
{
printf("fopen 打开失败!!\n");
return -1;//提前结束程序
}
printf("fopen 打开文件成功!!\n");
//2.关闭文件
fclose(fp1);
return 0;
}
2.3 fgets函数
fgets函数//file get string
(1)功能:每次读取一行内容 ,以\n作为读取的终止符
//把读到的一行内容看出字符串
(2)头文件及函数原型
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
(3)参数说明:
char *s //读到的内容存放地 ---》读完放哪
int size //最多读取的字符数
FILE *stream //fopen的返回值 文件流指针
//stream ---》流
(4)返回值:
成功:
读取到的一行内容的首地址
失败:
返回NULL//--->读取失败---》用来标识读取到文件末尾时
//调用参考
char buf[100] ;//用来保存读取到一行内容
fgets(buf,sizeof(buf),fp);
2.3.1fgets案例代码
#include <stdio.h>
int main(int argc, const char *argv[])
{
//1.打开
FILE* fp = fopen("./fopen.c","r");
if(fp == NULL)
{
printf("文件打开失败\n");
return -1;
}
//2.读写操作
char buf[100];//用来存放读取的一行内容
#if 0
fgets(buf,sizeof(buf),fp);
printf("%s",buf);
fgets(buf,sizeof(buf),fp);//调用第二次放buf中 会被覆盖
printf("%s",buf);
fgets(buf,sizeof(buf),fp);//调用第三次放buf中 会被覆盖
printf("%s",buf);
#endif
//循环读取全部内容
while(fgets(buf,sizeof(buf),fp) != NULL)//fgets读取到末尾时返回NULL
{
printf("%s",buf);//将读取的内容打印到终端
}
//3.关闭
fclose(fp);
return 0;
}
fgets注意事项
当存放读取内容的数组容量不够读取一行内容时,最多读取sizeof(buf)-1个字符,最后一个位置用于存放'\0'
char buf[10] ;
#include <stdio.h> //要读的第一行
fgets(buf,sizeof(buf),fp);
printf("%s",buf);// #include -->实际读取到9个字符
2.4 fputs函数
fputs函数 file put string
(1)功能:一次写入一个字符串
(2)头文件及函数原型
#include <stdio.h>
int fputs(const char *s, FILE *stream);
(3)参数说明:
const char *s //要写入内容的首地址
FILE *stream //fopen的返回值
(4)返回值:
成功:
>= 0 //实际写入的字符数
失败:
返回EOF
//调用参考
char buf[100] = "helloworld";
fputs(buf,fp);
2.4.1fputs案例代码
#include<stdio.h>
#include<string.h>
int main(int argc, const char *argv[])
{
//1.打开
FILE* fp = fopen("./name.txt","w");
if(fp == NULL)
{
printf("文件打开失败\n");
return -1;
}
char buf[100];//用于存放写入的内容
//2.读写操作
int i;
for(i = 0;i < 3;i++)
{
printf("请输入名字\n");
scanf("%s",buf);
//zhangsan\n
strcat(buf,"\n");
fputs(buf,fp);
fflush(fp);//写入一次刷新一次
}
//3.关闭
fclose(fp);
return 0;
}
//输入两次ctrl+c中止了 内容写入到缓存区中并没有写入到文件中。
2.5 fread函数
fread //file read
(1)功能: 每次读取一段内容,可以自己设定读取内容多少,但是以块为单位。
(2)头文件及函数原型
typedef int size_t;
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
(3)参数说明:
void *ptr //读取到的内容存放的首地址
size_t size //一块的大小 以字节为单位
size_t nmemb //一次最多读的块数
FILE *stream //fopen的返回值 文件流指针
(4)返回值:
成功:实际读取的块数
大于0的数
失败:小于0 //fread读取到文件末尾时的标识 < 0
//调用参考
char buf[100];//用于存放读取到的内容
int ret1 = fread(buf,1,100,fp);//1一块以一个字节为单位100最多读取100块
int ret2 = fread(buf,100,1,fp);//100一块的以100为单位,最多读取1块
int ret3 = fread(buf,2,50,fp);//2一块以2字节为单位,最多读取50块
int ret4 = fread(buf,4,25,fp);//4一块以4字节为单位,最多读取25块
//ret --->实际读取的块数
//ret1 = 5 实际读取的字节数1*5 = 5
//ret3 = 5 实际读取的字节数2*5 = 10
//ret4 = 5 实际读取的字节数4*5 = 20
返回值ret代表的是实际读取的块数 不等于 读取到字符数。
2.5.1 fread案例代码
#include <stdio.h>
int main(int argc, const char *argv[])
{
//一次读取文件中的所有内容
char buf[1000] = { 0 };
//1.打开文件
FILE *fp = fopen("./test.c","r");
if(fp == NULL)
{
perror("fopen failed");
return -1;
}
//2.读取内容到buf数组中
int ret = fread(buf, 1, 1000, fp);//1块的基本单位是1个字节,一次最多读取1000块
printf("ret is %d\n",ret);//实际读取块数
printf("%s",buf);
//3.关闭文件
fclose(fp);
return 0;
}
2.5.2 循环读取
#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
//循环读取文件中的所有内容
char buf[100] = { 0 };
//1.打开文件
FILE *fp = fopen("./test.c","r");
if(fp == NULL)
{
perror("fopen failed");
return -1;
}
//2.读取内容到buf数组中
while(fread(buf, 1, sizeof(buf),fp) > 0)//只要fread返回值>0,就说明实际读取到了块数
{
printf("%s",buf);
//为了解决最后一次读取打印有残留物bug,打印之后,清空buf数组
memset(buf, 0, sizeof(buf));//清空buf数组,让整个buf数组中每个字节的值都是0,0就是'\0'
}
//3.关闭文件
fclose(fp);
return 0;
}
2.6 fwrite函数
//file write
(1)功能:
按块写入内容 --》指定大小写入
(2)头文件及函数原型
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
(3)参数说明:
const void *ptr //要写入的内容的首地址
size_t size //一块的大小
size_t nmemb //实际写入的块数
FILE *stream //fopen的返回值
(4)返回值:
成功:
实际写入的块数
失败:
小于0
//调用参考
char buf[100] = "helloworld";
fwrite(buf,1,strlen(buf),fp);
2.6.1fwrite案例代码
#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
char buf[100] = "hello";//即将写入文件中的字符串
//1.打开文件
FILE *fp = fopen("./test.c","w");
if(fp == NULL)
{
perror("fopen failed");
return -1;
}
// fwrite(buf, 1, 3, fp);//将hel写入文件,也就是将buf数组的前3个字节写入文件 1*3 = 3个字节
fwrite(buf, 1, strlen(buf), fp);
//3.关闭文件
fclose(fp);
return 0;
}
2.7.sprintf、fprintf函数
sprintf和fprintf两个函数需要引入string.h头文件。
2.7.1printf函数
老朋友了,它的功能是将格式化后的内容写入在终端上。
int a = 100;
int b = 20;
printf("hellowrold\n");//一个参数
printf("a is %d\n",a); //两个参数
printf("a is %d,b is %d\n",a,b); //三个参数
在终端中得到以下内容:
helloworld
a is 100
a is 100,b is 20
2.7.2sprintf函数
功能:将格式化后的字符串写入到另一个字符串中
//调用参考
fprintf(fp,"hellowrold");//把helloworld写入到fp打开文件中
fprintf(fp,"a is %d,b is %d\n",a,b); //三个参数
int sprintf(char *str, const char *format, ...);
参数:
char *str //要写入的字符串首地址
const char *format //格式化字符串的首地址
2.7.3fprintf函数
功能:将格式化后的字符串写入在打开的文件中
//调用参考
fprintf(fp,"hellowrold");//把helloworld写入到fp打开文件中
fprintf(fp,"a is %d,b is %d\n",a,b); //三个参数
int sprintf(char *str, const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
参数:
FILE *stream //fopen 的返回值 文件流指针
const char *format //格式化后的字符串首地址
2.8 memset函数
功能:内存设置函数
需要引用头文件 string.h
原型:
void *memset(void *s, int c, size_t n);
参数说明:
void *s //要设置内存空间首地址
int c //要设置的值的ASCII码
size_t n //多个个字节
返回值: 被设置的内存空间的起始地址
示例:
char buf[100] = {0};
memset(buf,0,sizeof(buf));//将整个buf数组清零
#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
//memset memory set 内存设置函数
char buf[100] = "SSSSSSSSSSSSSSSSSSSSSS";
memset(buf, 'A', 5);//以字节为单位进行设置,将buf数组的前5个字节设置为'A'
puts(buf);
memset(buf, 0, sizeof(buf));
puts(buf);
return 0;
}
2.9 fseek函数
功能:移动文件指针位置
需要引用头文件:stdio.h
原型:
int fseek(FILE *stream, long offset, int whence);
参数说明:
FILE *stream //文件流指针fopen的返回值
long offset //偏移量
int whence //基准位
返回值:
成功: 0
失败: EOF -1
2.10 ftell函数
功能:获取文件指针位置
需要引用头文件:stdio.h
原型:
long ftell(FILE *stream);
参数说明:
FILE *stream//fopen的返回值
返回值
成功:返回文件指针当前位置
失败:EOF
2.10.1.fseek与ftell案例代码
#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
FILE* fp = fopen("./test.c","r");
if(fp == NULL)
{
printf("fopen failed\n");
return -1;
}
//成功打开
long post = ftell(fp);//获取文件指针
printf("post is %ld\n",post);
char buf[100];
fgets(buf,sizeof(buf),fp);//读取一行内容
post = ftell(fp); //再次获取
printf("post is %ld\n",post);
printf("%s",buf);
fseek(fp,-5,SEEK_CUR);//针对当前文件指针位置向前偏移5个字符
post = ftell(fp);
printf("post is %ld\n",post);
fseek(fp,15,SEEK_CUR);//针对当前文件指针位置向后偏移15个字符
post = ftell(fp);//再次获取
printf("post is %ld\n",post);
fseek(fp,0,SEEK_SET);//将文件指针移动到文件首
post = ftell(fp);//再次获取
printf("post is %ld\n",post);
fseek(fp,0,SEEK_END);//将文件指针移动到文件尾
post = ftell(fp);//再次获取
printf("post is %ld\n",post);//此时post的值正好是文件的字节数
fclose(fp);
return 0;
}
3.标准IO三个流
一个程序运行的时候,自动打开了三个流 standard //标准的 标准输入流 ---stdin --->默认从键盘输入读取数据 标准输出流 ---stdout --->默认往终端输出内容 标准错误流 ---stderr --->默认往终端输出内容 标准错误流(stderr)是程序输出错误信息的通道,通常用于显示错误和警告信息。它与标准输出流(stdout)和标准输入流(stdin)一起,是每个进程默认打开的三个文件描述符之一,分别对应0、1和2 3 标准错误流的主要特点是它不经过缓冲,意味着错误信息会立即输出到显示器,而不需要等待缓冲区满或遇到换行符1。这使得标准错误流非常适合用于输出紧急错误信息。
12.1示例
#include <stdio.h>
int main(int argc, const char *argv[])
{
//标准输出流和标准错误流, 标准错误流是无缓存的
fputs("hello\n",stdout);//stdout 默认是终端, 将"hello"写入到终端上,相当于打印输出
fputs("world\n",stderr);//stderr 默认是终端, 将"world"写入到终端上,相当于打印输出
//标准输入流
char buf[100] = { 0 };
fgets(buf, sizeof(buf), stdin);//stdin 默认是键盘, 从键盘输入中读取内容保存到buf数组中
printf("%s",buf);
return 0;
}
4.time ctime 和localtime
4.1time函数
time函数的功能:获取从1970-01-01 00:00:00 +0000 (UTC)距今的秒数
需要引用的头文件:time.h
原型:
typedef long time_t;
time_t time(time_t *t);
返回值:
time_t t;//---time_t 其实就是重命名的int类型,这样写是为了见名知意,后面还会有很多类似的重命名。
t = time(NULL);
参数上的地址传递:
time_t t;
time(&t);
4.2ctime
功能:将秒数转换为英文格式系统时间
原型:
char *ctime(const time_t *timep);
参数:const time_t *timep 距今的秒数
返回值: char * 英文格式时间字符串的首地址
4.3localtime
功能:将秒数转换为中文格式系统时间
参数:const time_t *timep 距今的秒数
返回值:struct tm *结构体指针,指向时间结构体的指针
struct tm {
int tm_sec; /* seconds 秒(范围:0-59) */
int tm_min; /* minutes 分钟(范围:0-59)*/
int tm_hour; /* hours 小时(范围:0-23)*/
int tm_mday; /* day of the month 一个月中的日期(范围:1-31)*/
int tm_mon; /* month 月份,从一月开始计数(范围:0-11) */
int tm_year; /* year 自1900年起的年数*/
int tm_wday; /* day of the week 星期几,从星期日开始计数(范围:0-6,0表示 星期日)*/
int tm_yday; /* day in the year 一年中的天数,从一月一日开始计数(范围:0- 365)*/
int tm_isdst; /* daylight saving time 夏令时标志(Daylight Saving Time),正数表示夏令时,0表示不使用夏令时,负数表示不确定夏令时状态*/
};
4.4ctime和localtime案例代码
#include <stdio.h>
#include <time.h>
int main(int argc, const char *argv[])
{
time_t t;//保存距今的秒数
struct tm* tp = NULL;//用来保存localtime返回值
while(1)
{
time(&t);//得到距今的秒数
//因为ctime返回值是英文格式字符串首地址,可以直接用%s输出
printf("%s", ctime(&t));
tp = localtime(&t);//将距今的秒数转换为具体时间
printf("%d-%02d-%02d %02d:%02d:%02d\n",tp->tm_year+1900,tp->tm_mon+1,
tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec);
sleep(1);
}
return 0;
}
5.linu文件IO
Linux操作系统自带的系统调用,没有缓存区。
5.1open函数
功能:打开文件的,open不仅能打开普通类型的文件还能打开其他类型的文件。fopen只能打开普通类型的文件
ls -l -普通文件 d目录文件 p管道文件 s套接字文件 l链接文件 b块设备文件
需要引用头文件:
#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);
参数说明:
const char *pathname //要打开文件的路径
int flags //打开模式
mode_t mode //新建文件的访问权限
O_RDONLY //只读
O_WRONLY //只写
O_RDWR //可读可写
O_TRUNC //清空
O_APPEND//追加
O_CREAT //创建
//当第二个参数中有O_CREAT时必须写第三个参数 0666
返回值:
每打开一个文件系统就会在内核空间开辟一块地方存放文件相关内容,open是通过文件描述符来区分打开的文件。
成功:返回一个非负的唯一的暂未被分配出去的最小的文件描述符
失败:回-1
//调用
#define O_RDONLY 1
int fd = open("./haha.c",O_RDONLY);//以只读的方式打开当前路径下的haha.c
//以可读可写的方式打开当前路径下haha.c没有创建 有清空
int fd = open("./haha.c",O_RDWR|O_CREAT|O_TRUNC,0666);
5.2文件权限掩码
在Linux中,文件权限掩码(umask)是一个权限掩码,用于限制新建文件的默认权限。
0 表示不掩盖(允许设置该权限)。 1 表示掩盖执行权限。 2 表示掩盖写入权限。 4 表示掩盖读取权限。
查看文件权限掩码命令: umask //0002 0八进制 002是默认掩码
修改文件权限掩码命令: umask 0000 //将掩码修改000
touch demo.c
ls -l demo.c
-rw-rw-r-- 1 linux linux 493 May 27 05:12 demo.c
rw-rw-r--//664
并不是
rw-rw-rw- // 666
5.3close函数
功能:关闭文件---释放内核空间
需要引用头文件:
#include <unistd.h>
原型:
int close(int fd);
参数说明:
int fd;//open函数返回值 打开的
返回值:成功: 0 失败:-1
5.3.1open和close案例代码
关于文件io需要引用的文件很多,也很烦,所以干脆都放在一个我们之间写好的头文件里,下次直接引用我们写的头文件就好了。这里有一些与进程线程与信号量相关的头文件,一起放弃进去,后续用的时候方便些。
#ifndef _MY_H
#define _MY_H
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>
#include <pthread.h> // p process进程 thread 线程
#include <semaphore.h> //semaphore信号量
#include <signal.h>
#include <sys/shm.h> //sh share m memory
#include <sys/msg.h> //msg message
#endif
由于后续函数需要的头文件各不相同,为了方便编写,这里写一个头文件,后面只要引用我们写的头文件即可,这个头文件包含了后续所有函数需要引用的头文件。
#include "my.h"//my.h是我们自己写的头文件
int main(int argc, const char *argv[])
{
//打开文件
//以可读可写,追加文件文件尾的方式打开文件,如果不存在,创建并打开,文件权限0666
int fd = open("xixi.c",O_RDWR | O_APPEND | O_CREAT, 0666);
if(fd == -1)//返回值是-1,打开失败
{
perror("open failed");
return -1;
}
printf("fd is %d\n",fd);//fd is 3
printf("open sucessful!!\n");
//关闭文件
close(fd);
return 0;
}
5.4read函数
功能:按字节读取
需要引用头文件:
#include <unistd.h>
原型:
size_t read(int fd, void *buf, size_t count);
参数说明:
int fd // open的返回值 文件描述符
void *buf //读取到内容的存放位置
size_t count //最多读取的字节数
返回值:read读取到文件末尾时 返回的是-1 read的返回值>0才代表读取到文件内容了。成功:实际读取的字节数。失败:-1
5.4.1read案例代码
#include "my.h"
int main(int argc, const char *argv[])
{
int fd = open("./01-fopen.c",O_RDWR);
if(fd == -1)
{
perror("open failed");
return -1;
}
char buf[100] = { 0 };//用来保存读取到的数据 n个字节
while(read(fd, buf, sizeof(buf)) > 0)//只要
{
printf("%s",buf);
memset(buf, 0, sizeof(buf));//清空buf数组,解决上一次读取残留物bug
}
close(fd);
return 0;
}
5.5write函数
功能:按字节写入
需要引用头文件:
#include <unistd.h>
原型:
size_t write(int fd, const void *buf, size_t count);
参数说明:
int fd //文件描述符 open的返回值
const void *buf //要写入的内容的首地址
size_t count //实际要写入的字节数
返回值:成功:实际写入的字节数。失败: -1
5.6lseek函数
功能:兼具了fseek和ftell两个函数的功能 移动文件指针的同时还获取文件指针位置。
需要引用头文件:
#include <sys/types.h>
#include <unistd.h>
原型:
off_t lseek(int fd, off_t offset, int whence);
//typedef long off_t;
参数说明:
int fd //文件描述符 open的返回值
off_t offset //偏移量 正数向后 负数向前
int whence //基准位
SEEK_SET//文件首
SEEK_END//文件尾
SEEK_CUR//文件指针当前位置
//偏移量:正数---》向后移动 负数----》向前移动
返回值:成功:就是返回值文件指针所在位置。失败:-1
5.6.1lseek案例代码
#include "my.h"
int main(int argc, const char *argv[])
{
//打开文件
int fd = open("./fopen.c",O_RDONLY);//以只读方式打开
if(fd == -1)
{
perror("open failed");
return -1;
}
long post = lseek(fd,0,SEEK_END);//将文件指针移动到文件尾
printf("post is %ld\n",post);
//关闭文件
close(fd);
return 0;
}
6 三个文件描述符
标准输入文件描述符 0 ---》键盘 标准输出文件描述符 1 ---》终端 标准错误文件描述符 2 ---》终端
#include "my.h"
int main(int argc, const char *argv[])
{
//0 标准输入,默认是键盘
char buf[100] = { 0 };
//scanf
read(0, buf, sizeof(buf));//从键盘输入读取
//1 标准输出,默认是终端
write(1, buf, strlen(buf));
//2 标准错误输出,默认是终端
write(2, buf, strlen(buf));
return 0;
}
7.标准IO和Linux文件IO区别
1.标准文件IO存在缓存区,系统文件IO没有缓存区 2.标准文件IO只能打开普通文件,系统文件IO可以打开不同类型的文件(普通文件、管道文件、套接字文件...) 3.标准文件IO用FILE*文件流指针来标识每个打开的文件 系统文件IO用int fd文件描述符来标识每个打开的文件 标准文件IO提供了2对读写操作函数 fopen fclose fgets fputs fread fwrite 系统文件IO提供了1对读写操作函数 open close read write
8.目录操作
8.1 stat 函数
功能:获取文件属性
需要引用头文件:
#include <sys / types.h>
#include <sys / stat.h>
#include <unistd.h>
原型:
int stat(const char *path, struct stat *buf);
参数说明:
const char *path //要获取文件的路径及名字
struct stat *buf //用来存放获取到的文件属性
返回值:获取是否成功 成功: 返回: 0 失败: 返回: -1
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等
ino_t st_ino; //inode节点号
dev_t st_dev; //设备号码
dev_t st_rdev; //特殊设备号码
nlink_t st_nlink; //文件的连接数
uid_t st_uid; //文件所有者
gid_t st_gid; //文件所有者对 应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //文件内容对应的块数量
};
8.1stat案例代码
#include "my.h"
int main(int argc, const char *argv[])
{
struct stat s = { 0 };//s用来保存文件的属性信息
int ret = stat("./02-test.c", &s);
if(ret == -1)//返回值是-1的时候,获取文件属性,失败
{
perror("stat failed");
return -1;
}
printf("文件大小:%ld 文件最后被修改时间:%s",s.st_size, ctime(&s.st_mtime));
return 0;
}
8.2opendir函数
功能:打开目录(diretory)文件
需要引用头文件:
#include <dirent.h>
原型:
DIR *opendir(const char *name);
参数说明:
const char *name // 要打开的目录的路径和名字
返回值:每打开一个目录,系统会在内核空间开辟内存,返回内核空间存放目录信息的首地址。成功: DIR* 目录流指FILE* 文件流指针。失败:NULL
8.3readdir函数
功能:调用依次读取一个目录中的一个文件
需要包含头文件:
#include <dirent.h>
原型:
struct dirent *readdir(DIR *dirp);
参数说明:
DIR *dirp //opendir的返回值 目录流指针
返回值: 成功: struct dirent * //用来保存从目录中读取文件的内容 失败: 返回 NULL //当目录文件读取到尾巴
struct dirent
{
long d_ino; /* inode number 索引节点号 */
off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
unsigned short d_reclen; /* length of this d_name 文件名长 */
unsigned char d_type; /* the type of d_name 文件类型 */
char d_name[NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}
8.4 closedir函数
功能:关闭目录文件
需要引用头文件:
#include <dirent.h>
原型:
int closedir(DIR *dirp);
参数说明:
DIR *dirp //opendir的返回值
返回值: 成功: 0 失败: -1