基于Linux使用C语言实现简单的目录管理

在Linux下,需要实现某个目录下文件的遍历的时候,可以使用opendir,readdir,closedir这些接口。这些接口使用说明如下所示:

1).opendir

DIR* opendir(const char * name);

#include <sys/types.h>

#include <dirent.h>

DIR *opendir(const char *name);

传入name路径,成功则返回非空DIR指针,否则返回NULL; 注意DIR前面没有struct,如果加上编译器会warning。

2).readdir

struct dirent *readdir(struct DIR* dir);

readdir一般要配合opendir使用,readdir不是线程安全函数,代替他的有readdir_r。

readdir返回 struct dirent *指针,读完目录下所有文件时,返回NULL。

3).closedir

void closedir(DIR* dir); 关闭打开的目录描述符dir,同时释放dir空间。Closedir需要配合opendir使用。

下面简单记录下这些接口的使用例子,主要涉及文件遍历,文件查找,文件模糊查找,文件删除,关键字查找并删除等功能。

1.首先在Linux系统下,在这里创建一个命名为"proj"测试的工程。

2.创建一个名为"dirtest.c"的源文件,粘贴如下所示的内容:

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <dirent.h>
#include<string.h>

//定义一些文件操作的宏
#define MODE_LIST_ALL_FILE 0                //列出所有文件
#define MODE_FIND_FILE 1					  //查找一个文件
#define MODE_DELETE_FILE 2                 //删除一个文件
#define MODE_FUZZY_SEARCH_FILE 3           //通过关键字匹配查找文件
#define MODE_FUZZY_SEARCH_DELETE_FILE 4    //通过关键字匹配查找并删除文件

/*
函数功能:列出该目录下的所有文件
*/
void list_all_files(DIR *dir)
{
	int index=0;
	struct dirent *d;
	while ((d = readdir(dir)) != NULL)
	{
		index++;
		LOG("[index %d]:%s\n", index, d->d_name);	
	}
		
}
/*
函数功能:查找文件
返回:1,成功找到;0:未找到文件
*/

int find_files(DIR *dir, char *file)
{
	struct dirent *d;
	int find = 0;
	while ((d = readdir(dir)) != NULL)
	{
//如果名称匹配上,则打印出该文件名称提示
		if(!strcmp(d->d_name, file)) {
			LOG("Locate the file named%s\n", d->d_name);
			find = 1;//返回结果置1
		}
	}
	return find;
}
/*
函数功能:通过关键字匹配查找文件
返回:1,成功找到;0:未找到文件
*/

int fuzzy_search_files(DIR *dir, char *keyword)
{
	struct dirent *d;
	int find = 0;
	while ((d = readdir(dir)) != NULL)
	{
//如果名称匹配上,则打印出该文件名称提示
		if(strstr(d->d_name, keyword)) {
			LOG("file :%s match!!!\n", d->d_name);
			find = 1;//返回结果置1
		}
	}
	return find;
}

/*
函数功能:删除一个文件
返回:1,成功找到,并删除该文件;0:未找到文件
*/
int delete_files(DIR *dir, char *test_dir, char *file)
{
	struct dirent *d;
	int find = 0;
	while ((d = readdir(dir)) != NULL)
	{
		if(!strcmp(d->d_name, file)) {
			char delete_file[64]="";
			sprintf(delete_file, "%s/%s", test_dir, file);//需要将路径+文件名才能正确删除
			unlink(delete_file);
			LOG("delete file:%s success!\n", delete_file);
			find = 1;
		}
	}
	return find;
}
/*
函数功能:删除通过关键字匹配上的文件
返回:1,成功找到,并删除该文件;0:未找到文件
*/
int delete_files_by_keyword(DIR *dir,  char *test_dir, char *keyword)
{
	struct dirent *d;
	int find = 0;
	while ((d = readdir(dir)) != NULL)
	{
		if(strstr(d->d_name, keyword)) {
			char delete_file[64]="";
			sprintf(delete_file, "%s/%s", test_dir, d->d_name);//需要将路径+文件名才能正确删除

			unlink(delete_file);
			LOG("delete file:%s success!\n", delete_file);
			find = 1;
		}
	}
	return find;
}
/*
函数功能:接收并解析命令行输入的参数
返回:无
*/

void dir_proc(char *argv[])
{
	char *dir_name = argv[1];
	int cmd_code = atoi(argv[2]);
	DIR *dir;
	struct dirent *d;
	dir = opendir(dir_name);
	if (!dir)
	{
		LOG("cannot open dir %s", dir_name);
		return ;
	}

//根据代号,作出不同的操作
	switch(cmd_code) {
		case MODE_LIST_ALL_FILE:
		{
            //显示该目录下的所有文件
			list_all_files(dir);
			break;
		}
		case MODE_FIND_FILE:
		{
//查找文件
			if(argv[3]) {
				if(!find_files(dir,argv[3])) {
					LOG("file name %s not found!\n", argv[3]);
				}
			}
			else {
				show_help();
			}
			break;
		}
		case MODE_DELETE_FILE:
		{
//删除文件
			if(argv[3]) {
				if(!delete_files(dir,argv[1], argv[3])) {
					LOG("file name %s not found!delete fail\n", argv[3]);
				}
			}
			else {
				show_help();
			}
			break;
		}
		case MODE_FUZZY_SEARCH_FILE:
		{
            //通过关键字查找文件

			if(argv[3]) {
				if(!fuzzy_search_files(dir, argv[3])) {
					LOG("file name search by keywords %s fail!\n", argv[3]);
				}
			}
			else {
				show_help();
			}
			break;
		}
		case MODE_FUZZY_SEARCH_DELETE_FILE:
		{
 //通过关键字查找,并删除文件
			if(argv[3]) {
				if(!delete_files_by_keyword(dir,argv[1], argv[3])) {
					LOG("file name search by keywords %s fail!\n", argv[3]);
				}
			}
			else {
				show_help();
			}
			break;
		}
		default:
		{
			LOG("command unkown!\n");
			break;
		}
	}
	closedir(dir);
}

3.创建一个名为"main.c"的文件,内容如下所示:

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <dirent.h>
#include<string.h>

/*
函数功能:日志打印
*/
void LOG(const char *format,...)
{
	va_list argptr;
	char buffer[2048];
	va_start(argptr,format);
	vsprintf(buffer,format,argptr);
	va_end(argptr);

	printf("%s", buffer);
}
/*
函数功能:显示菜单选项
*/
void show_help()
{
	LOG("Invalid parameter!\n");
	LOG("-h:Show help\n");
	LOG("0:List all files\n");
	LOG("1:Find a file, (for example: ./dirtest test_dir 1 a.txt)\n");
	LOG("2:Delete a file, (for example: ./dirtest test_dir 2 a.txt)\n");
	LOG("3:Fuzzy find file, (for example:  ./dirtest test_dir 3 a)\n");
	LOG("4:Delete files by keyword, (for example:  ./dirtest test_dir 4 a)\n");
}
/*
程序入口
*/
int main(int argc, char *argv[])
{
	LOG("run dir test!\n");
	if(argc<3) {
		show_help();
		exit(0);
	}
	dir_proc(argv);
	return 0;
}

4.创建一个编译的Makefile,方便编译整个工程,内容如下所示:

bash 复制代码
CPROG	= dirtest   #生成一个名为dirtest的目标文件
BIN     = $(CPROG) 
CC= gcc
OBJS=main.o dirtest.o

all: $(BIN) 
clean:
	rm -f $(OBJS) $(BIN)
$(BIN): $(OBJS)
	$(CC)  -o $(BIN) $(OBJS)   $(CFLAGS) $(LDFLAGS) $(CFLAGS_EXTRA) 

5.创建完dirtest.c,main.c,Makefile后,便可以编译了,在该工程目录下执行make clean;make,编译成功之后会生成一个名为 "dirtest"的可执行文件。如下图所示:

6.测试,在该路径下创建一个名为"test_dir"的目录,然后随意创建一些文件。如下图所示:

6.1列出路径下的所有文件

6.2查找文件

6.3删除文件

6.4关键字查找文件

6.5通过关键字查找,并删除文件

至此,上述功能已简单测试完毕。

总结:关于目录的操作例子就写到这里了,熟悉了这些操作,自然而然地可以自己先ls的命令了。在后续的工作中,如果有遇到针对目录以及里面相关文件的管理操作,就可以在这个例子的基础上进行快速改装了。

相关推荐
罗伯特祥15 分钟前
C调用gnuplot绘图的方法
c语言·plot
Jackey_Song_Odd30 分钟前
解决Ubuntu下无法装载 Windows D盘的问题
linux·ubuntu
乔巴不是狸猫1 小时前
第11周作业
linux
嵌入式科普1 小时前
嵌入式科普(24)从SPI和CAN通信重新理解“全双工”
c语言·stm32·can·spi·全双工·ra6m5
Bessssss2 小时前
centos权限大集合,覆盖多种权限类型,解惑权限后有“. + t s”问题!
linux·运维·centos
silver6873 小时前
Linux 下的 GPT 和 MBR 分区表详解
linux
lqqjuly3 小时前
特殊的“Undefined Reference xxx“编译错误
c语言·c++
R-sz3 小时前
14: curl#6 - “Could not resolve host: mirrorlist.centos.org; 未知的错误“
linux·python·centos
code_abc3 小时前
Shell 脚本编程基础:变量
linux
星如雨落3 小时前
Linux shell脚本对常见图片格式批量转换为PDF文件
linux·shell