基于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”的源文件,粘贴如下所示的内容:

#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”的文件,内容如下所示:

#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,方便编译整个工程,内容如下所示:

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的命令了。在后续的工作中,如果有遇到针对目录以及里面相关文件的管理操作,就可以在这个例子的基础上进行快速改装了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/467915.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯练习02随机数生成器

随机数生成器 介绍 实际工作中随机数的使用特别多&#xff0c;比如随机抽奖、随机翻牌。通过随机数还能实现很多有趣的效果&#xff0c;比如随机改变元素的位置或颜色。 本题需要在已提供的基础项目中使用JS知识封装一个函数&#xff0c;该函数可以根据需要&#xff0c;生成指…

Javaweb学习记录(二)web开发入门(请求响应)

第一个基于springboot的web请求程序 通过创建一个带有springboot的spring项目&#xff0c;项目会自动生成一个程序启动类&#xff0c;该类启动时会启动该整个项目&#xff0c;而我们需要写一个web请求类&#xff0c;要求在本地浏览器上发送请求后&#xff0c;浏览器显示Hello&…

排序问题—java实现

冒泡排序 算法思想&#xff1a; 每次比较相邻元素&#xff0c;若逆序则交换位置&#xff0c;每一趟比较n-1次&#xff0c;确定一个最大值。故需比较n趟&#xff0c;来确定n个数的位置。 外循环来表示比较的趟数&#xff0c;每一趟确定一个最大数的位置内循环来表示相邻数字两…

如何在wps的excel表格里面使用动态gif图

1、新建excel表格&#xff0c;粘贴gif图到表格里面&#xff0c;鼠标右键选择超链接。 找到源文件&#xff0c; 鼠标放到图片上的时候&#xff0c;待有个小手图标&#xff0c;双击鼠标可以放大看到动态gif图。 这种方式需要确保链接的原始文件位置和名称不能变化&#xff01;&a…

阿里云发布 AI 编程助手 “通义灵码”——VSCode更强了 !!

文章目录 什么是 通义灵码&#xff08;TONGYI Lingma&#xff09; 快速体验“通义灵码” 什么是“通义灵码”&#xff08;TONGYI Lingma&#xff09; 通义灵码&#xff08;TONGYI Lingma&#xff09;&#xff0c;是阿里云出品的一款基于通义大模型的智能编码辅助工具&#xff…

创建一个electron-vite项目

前置条件&#xff1a;非常重要&#xff01;&#xff01;&#xff01; npm: npm create quick-start/electronlatest yarn: yarn create quick-start/electron 然后进入目录&#xff0c;下载包文件&#xff0c;运行项目 到以上步骤&#xff0c;你已经成功运行起来一个 electr…

从底层结构开始学习FPGA(0)----FPGA的硬件架构层次(BEL Site Tile FSR SLR Device)

系列目录与传送门 《从底层结构开始学习FPGA》目录与传送门 Xilinx的FPGA&#xff0c;从硬件架构的角度可以划分为6个层次&#xff0c;从底层到顶层依次是&#xff1a; BEL&#xff08;最底层单元&#xff09;SiteTileFSRSLRDevice&#xff08;FPGA芯片&#xff09; 接下来我…

论文解析:V3D: Video Diffusion Models are Effective 3DGenerators

摘要&#xff1a; 自动三维生成最近引起了广泛关注。最近的方法大大加快了生成速度&#xff0c;但由于模型容量有限或三维数据&#xff0c;生成的物体通常不够精细。在视频扩散模型最新进展的推动下&#xff0c;我们引入了 V3D&#xff0c;利用预训练视频扩散模型的世界模拟能…

力扣17. 电话号码的字母组合

Problem: 17. 电话号码的字母组合 文章目录 思路及解法复杂度Code 题目描述 思路及解法 1.将电话号码和对应的数组存入数组中创建映射关系&#xff1b; 2.编写&#xff0c;并调用回溯函数&#xff0c;当决策阶段等于digits的长度时&#xff0c;将当前的决策路径添加到结果集合中…

自学Python第二十九天-feapder框架创建爬虫

自学Python第二十九天-feapder框架创建爬虫 安装feapder 的设计架构feapder 框架的简单使用简单创建爬虫简单爬取数据简单的数据保存 中间件校验浏览器渲染使用浏览器渲染获取接口数据 feapder是一款上手简单&#xff0c;功能强大的 Python爬虫框架&#xff0c;内置 AirSpide…

linux安装WordPress问题汇总,老是提示无法连接到FTP服务器解决方案

最近在做一些建站相关的事情&#xff0c;遇到一些大大小小的问题都整理在这里 1.数据库密码和端口&#xff0c;千万要复杂一点&#xff0c;不要使用默认的3306端口 2.wordpress算是一个php应用吧&#xff0c;所以安装流程一般是 apache http/nginx——php——mysql——ftp &…

嵌入式学习第二十九天!(数据结构的概念、单向链表)

数据结构&#xff1a; 1. 定义&#xff1a; 一组用来保存一种或者多种特定关系的数据的集合&#xff08;组织和存储数据&#xff09; 1. 程序设计&#xff1a; 将现实中大量而复杂的问题以特定的数据类型和特定的数据结构存储在内存中&#xff0c;并在此基础上实现某个特定的功…

Python深度学习技术教程

原文链接&#xff1a;Python深度学习技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247597949&idx4&sn65c0d353d02b060fec98ec799f217ae1&chksmfa823e9acdf5b78cd71cfcb060e3b60125b17afbe3e19ef423d4709d2df7fc93d90ce3097253&token14787…

【K8S】docker和K8S(kubernetes)理解?docker是什么?K8S架构、Master节点 Node节点 K8S架构图

docker和K8S理解 一、docker的问世虚拟机是什么&#xff1f;Docker的问世&#xff1f;docker优点及理解 二、Kubernetes-K8SK8S是什么&#xff1f;简单了解K8S架构Master节点Node节点K8S架构图 一、docker的问世 在LXC(Linux container)Linux容器虚拟技术出现之前&#xff0c;业…

汽车功能安全整体方法

摘 要 ISO26262道路车辆功能安全标准已经制定实践了多年&#xff0c;主要目标是应对车辆的电子和电气&#xff08;E/E&#xff09;系统失效。该方法践行至今&#xff0c;有些系统功能安全方法已经成熟&#xff0c;例如电池管理系统&#xff08;BMS&#xff09;&#xff0c;并且…

Javaweb学习记录(三)请求响应案例

下面为一个请求响应案例&#xff0c;postman发送请求&#xff0c;服务器响应将一个xml文件中的数据通过读取解析&#xff0c;将其用Result类标准的格式返回前端&#xff0c;在前端用json的方式显示 后端Controller代码 1、通过本类的字节码文件得到类加载器并寻找到需要解析的…

vue2使用webSocket双向通讯

基于webSocket实现双向通信&#xff0c;使用webworker保持心跳。 由于浏览器的资源管理策略会暂停或限制某些资源的消耗&#xff0c;导致前端心跳包任务时效&#xff0c;后端接收不到webSocket心跳主动断开&#xff0c;因此需要使用webworker保持心跳 引入webworker npm insta…

【Ubuntu】Ubuntu的安装和配置

下载ubuntu镜像 https://releases.ubuntu.com/22.04.4/ubuntu-22.04.4-desktop-amd64.iso 一、Ubuntu安装 1.新建虚拟机 1.1按照它的提示创建用户&#xff1b;后面一直下一步就好 2.启动Ubuntu虚拟机 2.1设置为中文键盘 2.2默认即可&#xff1b;若是有低需求也可以选择最小…

Coursera上Golang专项课程3:Concurrency in Go 学习笔记(完结)

Concurrency in Go 本文是 Concurrency in Go 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 Concurrency in GoMODULE 1: Why Use Concurrency?Learning Objectives M1.1.1 - Parallel ExecutionM1.1.2 - Von Neumann BottleneckM1.1.3 - Power W…

Python基础(六)之数值类型元组

Python基础&#xff08;六&#xff09;之数值类型元组 1、简介 元组&#xff1a; 在Python中是内置的数据结构之一&#xff0c;是一个不可变的序列,切可以是任何类型数据。元组的元素放在&#xff08;&#xff09;小括号内。一般我们希望数据不改变的时候使用 不可变与可变的…