Linux C/C++ 文件和目录操作
UNIX文件系统是目录和文件的一种结构。所有东西的起点是称为根的目录,这个目录的名称是一个字符“/”。
目录是一个包含项的文件。在逻辑上,可以认为每个目录项都包含一个文件名,同时还包含说明该文件属性的信息。那什么又是文件属性呢?文件属性是指文件的类型、文件大小、文件所有者等等。
我们要介绍的就是怎么列出一个目录的所有文件名字以及文件的大小。
opendir(打开目录)
opendir() 函数打开一个目录流(stream) ,参数是目录的路径, 返回指向这个目录的流指针。这个流指针指向打开目录的第一个记录项。
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
打开成功,返回指向目录流的指针;打开失败,则返回NULL,并设置相应的错误代码errno。
readdir(读取目录)
#include <sys/types.h>
#include <dirent.h>
struct dirent *readdir(DIR *dir);
成功则返回下个目录进入点。有错误发生或读取到目录文件尾则返回NULL。
在Linux中, dirent structure的定义大致如下:
```c
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* 到下一个dirent的偏移 */
unsigned short d_reclen; /* 本记录项的长度 */
unsigned char d_type; /* 文件的类型,不支持所有文件系统*/
char d_name[256]; /* filename */
};
closedir(关闭目录)
closedir() 函数关闭一个目录流指针关联的目录。一次成功的调用closedir() 将闭底层的文件描述符与各种相关联。在此调用后,目录流描述符各种不可用。
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
ls命令的简要实现:
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
DIR *dp;
struct dirent *dirp;
if (argc != 2){
printf("Usage:%s filename\n\a", argv[0]);
exit(1);
}
if ((dp = opendir(argv[1])) == NULL){
printf("Open Directory %s Error:%s\n",argv[1], strerror(errno));
exit(1);
}
while((dirp = readdir(dp)) != NULL){
printf("%s\n",dirp->d_name);
}
closedir(dp);
return 0;
}
编译运行:
打印目录中各个文件的名字,不显示其他信息。这里要注意一下:我们使用opendir、readdir、closedir必须要包含一个系统文件 dirent.h
在Centos中,/usr/include/dirent.h 声明了函数原型。
获取目录下的文件大小
写一个例子,如果是一个目录我们输出这个目录下所有文件的大小。
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
int get_dir_size(char *dir_path, int64_t *dir_size)
{
DIR *dir;
struct dirent *dirp;
char file_abs_path[256];
struct stat buf;
int64_t total_size_byte = 0;
dir = opendir(dir_path);
if(NULL == dir)
{
return 1;
}
while(NULL != (dirp = readdir(dir)))
{
if(DT_DIR == dirp->d_type)
{
printf("dir %s jump\n",dirp->d_name);
continue;
}
/* file type */
snprintf(file_abs_path,sizeof(file_abs_path),"%s/%s",dir_path,dirp->d_name);
if(stat(file_abs_path,&buf))
{
printf("%s stat error.\n",file_abs_path);
continue;
}
printf("%s file size %d\n",file_abs_path,buf.st_size);
total_size_byte += buf.st_size;
}
*dir_size = total_size_byte;
closedir(dir);
return 0;
}
int main(int argc, char **argv){
int ret = 0;
int64_t dir_size;
if (argc < 2){
printf("Not input dir name\n");
return -1;
}
ret = get_dir_size(argv[1],&dir_size);
printf("dir_size %lld\n",dir_size);
return 0;
}
编译输出:
总结
本篇介绍如果使用opendir、readdir、closedir对目录进行处理。使用opendir函数返回指向DIR结构的指针。DIR是在目录项格式头文件dirent.h中定义的,它表示一个目录流类型。
在循环中调用readdir来读每个目录项,它返回一个指向dirent结构的指针。在dirent结构中取出的只是每个目录项的名字。使用该名字,就可调用stat函数以获取该文件的所有属性。
参考:UNIX 环境高级编程。
公众号-程序猿编码欢迎关注公众号【程序猿编码】,添加本人微信号(17865354792),回复:领取学习资料。或者回复:进入技术交流群。网盘资料有如下: