目录操作 目录也是被当作文件。
1.打开目录 或的DIR 指针,目录流指针 。表示整个目录的信息。opendir
2.读取目录内容 (写入目录,新建文件,删除文件,新建目录,删除目录,有独立函数) 。dirent 指针,表示目录的一个内容项.readdir
3.关闭目录 closedir
opendir
DIR *opendir(const char *name);
功能:
打开一个目录获得一个目录流指针
参数:
name:目录名
返回值:
成功返回目录流指针(类似于FILE*)
失败返回NULL
readdir
struct dirent *readdir(DIR *dirp);
功能: 从目录流中读取文件信息并将保存信息的结构体地址返回
参数: dirp:目录流指针
返回值: 包含文件信息的结构体
出错或者读到目录流末尾返回NULL
代码示例如下(实现目录下文件的遍历并打印文件名)
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <dirent.h> int main(int argc, char **argv) { DIR *dir = opendir("."); //这里"."的意思是当前目录 if (NULL == dir) //判断是否打开成功 { fprintf(stderr, "opendir error\n"); return 1; } while (1) { struct dirent *info = readdir(dir); //读取打开的目录流指针 if (NULL == info) { break; } printf("%s\n", info->d_name); } closedir(dir); return 0; }这个结构体原型如下,被定义在头文件<dirent.h>里,readdir读取dir后的返回值类型就是这个结构体类型,可以访问读取的目录项文件名和类型
struct dirent {
ino_t d_ino; // inode号,%lu打印
off_t d_off;
unsigned short d_reclen;
unsigned char d_type; // 文件类型 DT_DIR / DT_REG / DT_UNKNOWN
char d_name[256]; // 文件名!字符串,char数组
};
closedir
int closedir(DIR *dirp);
功能:关闭之前已经打开的目录流对象
参数:opendir的返回结果中目录流对象
返回值:成功 0
失败 -1;
目录辅助函数
chdir ,切换当前工作路径。
getcwd 获得当前路径
mkdir 新建目录
rmdir 删除目录 ,被操作的目录必须为空
如下是chdir代码示例(返回上一层目录,创建文件"aaa")
#include<stdio.h> #include<stdlib.h> #include<unistd.h> int main(int argc, char **argv) { int ret = chdir("../"); //".."是返回上一层目录 if(-1 == ret) { fprintf(stderr,"chdir error\n"); return 1; } FILE* fp = fopen("aaa","w"); fclose(fp); return 0; }如下是获取当前目录路径的示例
#include<stdio.h> #include<stdlib.h> #include<unistd.h> int main(int argc, char **argv) { char buf[512] = {0}; getcwd(buf, sizeof(buf)); //把当前路径变成字符串放到buf里 printf("before chdir:%s\n",buf); int ret = chdir(".."); //回到上一层目录 if(ret == -1) { fprintf(stderr,"chdir error\n"); return 1; } getcwd(buf,sizeof(buf)); //因为此时已经在上一层目录了,所以buf获取的是上一层目录的路径的字符串 printf("after chdir:%s\n",buf); return 0; }如下是创建一个目录的示例
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include<sys/stat.h> int main(int argc, char **argv) { int ret = mkdir("123", 0777); //0777是因为需要用执行权或者说运行权(x)才能进入目录 if(-1 == ret) { fprintf(stderr,"mkdir error\n"); return 1; } return 0; }如下是删除目录代码示例
#include<stdio.h> #include<unistd.h> int main(int argc, char **argv) { int ret = rmdir("123"); if(-1 == ret) { fprintf(stderr,"rmdir error\n"); return 1; } return 0; }stat, 最常用的成员是 st_size ,表示文件的大小(字节)
int stat(const char *path, struct stat *buf);
功能:
获得文件的属性
参数:
path: 文件的路径
buf: 属性存放空间的首地址
返回值:
成功返回0
失败返回-1
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include<stdio.h> #include<stdlib.h> int main(int argc, char **argv) { struct stat st; int ret = stat("01ls.c", &st); //把获取的属性返回到结构体类型的st中 if(-1 == ret) { fprintf(stderr,"stat error\n"); return 1; } printf("ino:%lu,mode:%d,link:%lu,uid:%d,gid:%d,size:%lu,tm:%lu\n",st.st_ino,st.st_mode,st.st_nlink,st.st_uid ,st.st_gid,st.st_size,st.st_mtim.tv_sec); return 0; }打印结果如下ino:1477777,mode:33188,link:1,uid:1000,gid:1000,size:397,tm:1792637744
这些是没有转换为可视的结果,比如tm是秒数,正常应该是表示的时间
结构体原型如下,每个成员都表示一些文件的状态
时间相关
在linux系统中,记录实际的方式,是记录秒数。unix 时间戳(从 1970 1-1 0:0:0 开始记录的秒数)。
time函数
time_t time(time_t *t);
功能: 获得1970年到现在的秒数
参数: t:存放秒数的空间首地址
返回值: 成功返回1970年到现在的秒数
失败返回-1
用法1:传 NULL,返回值拿时间戳(最常用)
time_t t = time(NULL);
printf("时间戳:%ld\n", t);
意思:不通过参数带出,直接把秒数作为返回值给你
用法2:传一个 time_t 变量的地址,通过参数带出
time_t t;
time(&t); // 把当前时间戳存入变量t
printf("时间戳:%ld\n", t);
注意:这两种效果完全一样!
time示例如下
#include<stdio.h> #include<time.h> int main(int argc, char **argv) { time_t sec = time(NULL); printf("sec = %lu\n",sec); return 0; }localtime struct tm *localtime(const time_t *timep);
功能:
将一个秒数转化成日历时间
参数:
timep:保存秒数空间的地址
返回值:
成功返回保存日历时间结构体的指针
失败返回NULL
ctime
char *ctime(const time_t *timep);//date
功能:
将时间秒数转化成字符串(完整的年月日时分秒字符串)
参数:
timep:保存时间空间的地址
返回值:
成功返回获得时间字符串的首地址
失败返回NULL
localtime和ctime示例如下
#include<stdio.h> #include<time.h> int main(int argc, char **argv) { time_t tm = time(NULL); struct tm* timeinfo = localtime(&tm); printf("%d-%d-%d %d-%d-%d\n",timeinfo->tm_year + 1900,timeinfo->tm_mon + 1,timeinfo->tm_mday ,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec); char *data = NULL; data = ctime(&tm); printf("%s\n",data); return 0; }打印结果如下
2026-10-22 20-4-0
Thu Oct 22 20:04:00 2026
系统报错相关函数
perror
void perror(const char *s);-->strerror() stderr
功能:
打印s字符串和errno对应的错误信息
参数:
s:要打印在终端上的出错信息
返回值:
void
#include<stdio.h> #include<errno.h> //errno头文件,即获取错误的返回值,系统调用/库函数出错的时候,内核/库自动给它赋值 int main(int argc, char **argv) { FILE* fp = fopen("123","r"); if(NULL == fp) { perror("fopen"); //打印该函数错误原因 printf("%d\n",errno); return errno; } return 0; }上面的errno的数值其实就是各种错误的编号数值,理解如下代码,可以用strerror把数值对应的错误打印出来
#include<stdio.h> #include<errno.h> #include<string.h> int main(int argc, char **argv) { int i; for(i = 0;i < 3;i++) { printf("num:%d error:%s\n",i,strerror(i)); } return 0; }打印结果如下
num:0 error:Success(return 0 即成功)
num:1 error:Operation not permitted (操作出错)
num:2 error:No such file or directory (没有这个文件)