目录
目录操作
目录的操作步骤:打开目录--->读取目录--->关闭目录
一、opendir函数
DIR *opendir(const char *name);
功能:用于打开一个目录,并获取一个与之相关的目录流指针。
参数:name:要打开的目录的名称。
返回值:
• 成功时,返回指向目录流的指针。
• 失败时,返回 NULL 。
二、readdir函数
struct dirent *readdir(DIR *dirp);
功能:从指定的目录流中读取文件或子目录的信息,并返回一个包含这些信息的结构体的地址。
参数:dirp:目录流指针。
返回值:
• 成功时,返回一个指向包含文件信息的 struct dirent 结构体的指针。
• 出错或者读到目录流末尾时,返回 NULL 。
三、closedir函数
int closedir(DIR *dirp);
功能:关闭之前通过 opendir 函数打开的目录流对象。
参数:dirp:opendir 函数的返回结果,即目录流对象。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 。
实现命令 ls 的功能:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, const char *argv[])
{
DIR* dir = opendir("./"); // ./ 为打开当前目录
if( dir==NULL )
{
fprintf(stderr,"opendir error\n");
return 1;
}
while(1)
{
struct dirent * info = readdir(dir); //readdir()是一个一个读取,所以要加循环
if( info == NULL ) //读完目录下所有文件后,返回空,就是读取结束条件
{
break;
}
switch (info->d_type)
{
case DT_DIR:
printf("目录文件 ");
break;
case DT_REG:
printf("普通文件 ");
break;
case DT_UNKNOWN:
printf("其他文件 ");
break;
default:
printf("未知文件 ");
break;
}
printf("%s\n",info->d_name); //结构体类型,输出要指向结构体成员
}
printf("\n");
closedir(dir); //关闭目录
return 0;
}
四、chdir函数
int chdir(const char *path);
功能:用于更改当前程序的工作路径。
参数:path:要更改到的目标路径。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 。
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
int ch = chdir(".."); //退回到上一级目录
if( ch==-1 )
{
fprintf(stderr,"chdir error\n");
return 1;
}
fopen("aaa","w"); //因为运行时在终端看不到效果
//所以在上一级创建一个文件以显示效果
return 0;
}
五、getcwd函数
char *getcwd(char *buf, size_t size);
功能:获取当前程序的工作路径。
参数:
• buf:用于保存工作路径的缓冲区的首地址。
• size:缓冲区的大小。
返回值:
• 成功时,返回保存路径的缓冲区的首地址。
• 失败时,返回 NULL 。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
// 定义一个 256 字节大小的字符数组,并初始化为 0
char buf[256]={0};
// 获取当前工作路径,并将其存储在 buf 中
getcwd(buf,sizeof(buf));
// 打印当前工作路径
printf("current path is %s\n",buf);
// 更改工作路径到上一级目录
chdir("../");
// 再次获取当前工作路径,并存储在 buf 中
getcwd(buf,sizeof(buf));
// 打印更改后的工作路径
printf("change path is %s\n",buf);
return 0;
}
六、mkdir函数
int mkdir(const char *pathname, mode_t mode);
功能:用于创建一个新的目录。
参数:
• pathname:要创建的目录的路径。
• mode:指定目录的权限模式。权限模式通常与当前进程的 umask 值进行运算,实际创建的目录权限为 mode & ~umask 。例如,常见的权限值如 0777 表示拥有完全权限。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 。
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, const char *argv[])
{
int ret = mkdir("./aaa",0777); //在当前目录下创建名为aaa的目录
if(ret==-1)
{
fprintf(stderr,"mkdir error\n");
return 1;
}
return 0;
}
七、rmdir函数
int rmdir(const char *pathname);
功能:删除一个空的目录。
参数:pathname:要删除的空目录的名称。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 。
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
int ret = rmdir("./aaa"); //在当前目录下把aaa删除
if(ret == -1)
{
fprintf(stderr,"rmdir error\n");
return 1;
}
return 0;
}
八、stat 函数
int stat(const char *path, struct stat *buf);
功能:获取指定文件的属性信息,包括文件的大小、创建时间、修改时间、访问权限等。
参数:
• path:要获取属性的文件的路径。
• buf:用于存储文件属性信息的 struct stat 类型结构体的指针。
返回值:
• 成功时,返回 0 。
• 失败时,返回 -1 ,并设置 errno 来指示错误类型。
实现指令 ll 的功能:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, const char *argv[])
{
struct stat st;
char pathname[] = "./01ls.c";
int ret = stat(pathname,&st);
if( ret == -1 )
{
fprintf(stderr,"stat error\n");
return 1;
}
//以下都需要man 7 inode 进入手册查询对应的宏
if(S_ISREG(st.st_mode))
{
fputc('-',stdout);
}
else if(S_ISDIR(st.st_mode))
{
fputc('d',stdout);
}
else if(S_ISCHR(st.st_mode))
{
fputc('c',stdout);
}
else if(S_ISBLK(st.st_mode))
{
fputc('b',stdout);
}
else if(S_ISFIFO(st.st_mode))
{
fputc('f',stdout);
}
else if(S_ISLNK(st.st_mode))
{
fputc('l',stdout);
}
else if(S_ISSOCK(st.st_mode))
{
fputc('o',stdout);
}
if(st.st_mode & S_IRUSR)
{
fputc('r',stdout);
}
else
{
fputc('-',stdout);
}
if(st.st_mode & S_IWUSR)
{
fputc('w',stdout);
}
else
{
fputc('-',stdout);
}
if(st.st_mode & S_IXUSR)
{
fputc('x',stdout);
}
else
{
fputc('-',stdout);
}
if(st.st_mode & S_IRGRP)
{
fputc('r',stdout);
}
else
{
fputc('-',stdout);
}
if(st.st_mode & S_IWGRP)
{
fputc('w',stdout);
}
else
{
fputc('-',stdout);
}
if(st.st_mode & S_IXGRP)
{
fputc('x',stdout);
}
else
{
fputc('-',stdout);
}
if(st.st_mode & S_IROTH)
{
fputc('r',stdout);
}
else
{
fputc('-',stdout);
}
if(st.st_mode & S_IWOTH)
{
fputc('w',stdout);
}
else
{
fputc('-',stdout);
}
if(st.st_mode & S_IXOTH)
{
fputc('x',stdout);
}
else
{
fputc('-',stdout);
}
//-rw-rw-r-- 1 linux linux 587 8月 14 11:37 01ls.c
printf(" %lu %u %u %lu %lu %s\n"
,st.st_nlink,st.st_uid,st.st_gid,st.st_size,st.st_mtime,pathname);
return 0;
}
获取时间的函数
一、time函数
time_t time(time_t *t);
功能:获取从 1970 年 1 月 1 日 00:00:00 UTC 到当前时刻的秒数。
参数:
t:用于存储秒数的指针。
返回值:
• 成功时,返回从 1970 年至今的秒数。
• 失败时,返回 -1 。
二、localtime函数
struct tm *localtime(const time_t *timep);
功能:
将从 time 函数获取的秒数转换为本地日历时间,并以 struct tm 结构体的形式返回。
参数:
timep:保存秒数的地址。
返回值:
• 成功时,返回指向 struct tm 结构体的指针。
• 失败时,返回 NULL 。
可以通过结构体元素,随意组合输出自己想要的效果。
三、ctime函数
char *ctime(const time_t *timep);
功能:
将从 time 函数获取的秒数转换为易于阅读的字符串形式。但是形式是固定的。
参数:
timep:保存秒数的地址。
返回值:
• 成功时,返回表示时间的字符串的首地址。
• 失败时,返回 NULL
#include <stdio.h>
#include <time.h>
int main(int argc, const char *argv[])
{
time_t tm;
time(&tm); 1
printf("%ld\n",tm);
printf("%s",ctime(&tm)); 3
struct tm *t = localtime(&tm); 2
printf("%d-%d-%d %d:%d;%d\n",
t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour
,t->tm_min,t->tm_sec);
return 0;
}