获取文件夹下所有文件,支持windows和linux系统

最近项目中需要用到遍历出指定文件夹下所有文件列表,又没有现成得接口,只能通过调用系统接口实现,于是查阅和整理了一下,写了一个支持跨平台(windows和linux系统)的接口:

/**************************************************************
 * 功能:遍历文件夹下所有文件列表,目前只支持一级目录
 * 输入参数:
 *		strFileFolder:文件夹
 * 输出参数:
 *		vtFilePaths:文件列表
 * ************************************************************/
void getFilePaths(const std::string& strFileFolder, std::vector<std::string>& vtFilePaths);

具体实现如下:

#include <iostream>
#include <string>
#include <stdlib.h>
#include <string.h>
#ifdef __linux__
#include <dirent.h>
#else
#include <io.h>
#endif // __linux__
#include <vector>

/**************************************************************
 * 功能:遍历文件夹下所有文件列表,目前只支持一级目录
 * 输入参数:
 *		strFileFolder:文件夹
 * 输出参数:
 *		vtFilePaths:文件列表
 * ************************************************************/
void getFilePaths(const std::string& strFileFolder, std::vector<std::string>& vtFilePaths)
{
#ifdef __linux__
	DIR* pDir = nullptr;

	if (!(pDir = opendir(strFileFolder.data())))
	{
		std::cout << "file folder doesn't exist!" << std::endl;
		return;
	}

	struct dirent* ptr = nullptr;
	while (0 != (ptr = readdir(pDir)))
	{
		if (0 != strcmp(ptr->d_name, ".") && 0 != strcmp(ptr->d_name, ".."))
		{
			vtFilePaths.emplace_back(strFileFolder + "/" + ptr->d_name);
		}
	}

	closedir(pDir);
#else
	struct _finddata_t fileInfo;
	//std::string strFileInfo = strFileFolder + "/*.jpg"; // ok
	std::string strFileInfo = strFileFolder + "/*.*"; // ok
	//std::string strFileInfo = strFileFolder + "\\*"; // ok
	long long hFd = _findfirst(strFileInfo.data(), &fileInfo);
	if (-1 == hFd)
	{
		_findclose(hFd);
		std::cout << "file folder _findfirst error!" << std::endl;
		return;
	}

	std::string strFilePath = "";
	do
	{
		strFilePath = strFileFolder + "/" + fileInfo.name;
		if (_A_ARCH == fileInfo.attrib)
		{
			vtFilePaths.emplace_back(strFilePath);
		}
	} while (0 == _findnext(hFd, &fileInfo));

	_findclose(hFd);
#endif

	return;
}

测试用例如下:

void getFilePathsTest()
{
	std::string strFileFolder = "./data/images";
	std::vector<std::string> vtFilePaths;
	getFilePaths(strFileFolder, vtFilePaths);

	size_t size = vtFilePaths.size();
	printf("%s file count: %d.\r\n", strFileFolder.data(), size);
	for (size_t i = 0; i < 8 && i < size; ++i)
	{
		printf("file: %s.\r\n", vtFilePaths.at(i).data());
	}

	strFileFolder = "./data/radars";
	vtFilePaths.clear();
	getFilePaths(strFileFolder, vtFilePaths);

	size = vtFilePaths.size();
	printf("%s file count: %d.\r\n", strFileFolder.data(), size);
	for (size_t i = 0; i < 8 && i < size; ++i)
	{
		printf("file: %s.\r\n", vtFilePaths.at(i).data());
	}

	strFileFolder = "./data/cans";
	vtFilePaths.clear();
	getFilePaths(strFileFolder, vtFilePaths);

	size = vtFilePaths.size();
	printf("%s file count: %d.\r\n", strFileFolder.data(), size);
	for (size_t i = 0; i < 8 && i < size; ++i)
	{
		printf("file: %s.\r\n", vtFilePaths.at(i).data());
	}

	return;
}

扩展业务:

#include <math.h>
#include <cmath>

// 文件概要信息
struct FileAbsInfo
{
	std::string strPath;
	uint64_t ui64Timestamp;

	FileAbsInfo()
	{
		strPath = "";
		ui64Timestamp = 0;
	}
};

// 文件查找参数
struct FindParam
{
    bool bQueryAll;
	size_t iSrcFolderSize;
	size_t iIndexPos;
	size_t iOffset;
	int iTimeSpan; // 单位ms
	uint64_t ui64Timestamp; // 单位ms
	double dRatio;

    FindParam()
    {
        memset(this, 0, sizeof (FindParam));
    }
};

bool compareFileInfo(const FileAbsInfo& info1, const FileAbsInfo& info2)
{
	//return (info1.ui64Timestamp > info2.ui64Timestamp); // 降序
    return (info1.ui64Timestamp < info2.ui64Timestamp); // 升序
}

uint64_t getFileTimestamp(const std::string& strFileName)
{
	uint64_t ui64Timestamp = 0;
	size_t pos = strFileName.find_first_of('.');
	if (std::string::npos != pos)
	{
		std::string strTimestamp = strFileName.substr(0, pos);
		ui64Timestamp = std::stoull(strTimestamp);
	}

	return ui64Timestamp;
}

void getFilePaths(const std::string& strFileFolder, std::vector<FileAbsInfo>& vtFileInfos)
{
#ifdef __linux__
	DIR* pDir = opendir(strFileFolder.data());

	if (!pDir)
	{
		std::cout << "file folder doesn't exist!" << std::endl;
		return;
	}

	FileAbsInfo stFileInfo;
	struct dirent* ptr = nullptr;
	while (0 != (ptr = readdir(pDir)))
	{
		if (0 != strcmp(ptr->d_name, ".") && 0 != strcmp(ptr->d_name, ".."))
		{
			stFileInfo.strPath = strFileFolder + "/" + ptr->d_name;
			stFileInfo.ui64Timestamp = getFileTimestamp(ptr->d_name);
			vtFileInfos.emplace_back(stFileInfo);
		}
	}

	closedir(pDir);
#else
	struct _finddata_t fileInfo;
	//std::string strFileInfo = strFileFolder + "/*.jpg"; // ok
	std::string strFileInfo = strFileFolder + "/*.*"; // ok
	//std::string strFileInfo = strFileFolder + "\\*"; // ok
	long long hFd = _findfirst(strFileInfo.data(), &fileInfo);
	if (-1 == hFd)
	{
		_findclose(hFd);
		std::cout << "file folder _findfirst error!" << std::endl;
		return;
	}

	FileAbsInfo stFileInfo;
	do
	{
		if (_A_ARCH == fileInfo.attrib)
		{
			stFileInfo.strPath = strFileFolder + "/" + fileInfo.name;
			stFileInfo.ui64Timestamp = getFileTimestamp(fileInfo.name);
			vtFileInfos.emplace_back(stFileInfo);
		}
	} while (0 == _findnext(hFd, &fileInfo));

	_findclose(hFd);
#endif

	sort(vtFileInfos.begin(), vtFileInfos.end(), compareFileInfo);

	return;
}

std::string getRelateFilePath(const FindParam& stFindParam, std::vector<FileAbsInfo>& vtFileInfo)
{
	std::string strPath = "";
	size_t iFolderSize = vtFileInfo.size();

	int iStPos = 0, iEdPos = static_cast<int>(iFolderSize);
	if (!(stFindParam.bQueryAll))
	{
		iStPos = static_cast<int>(stFindParam.dRatio * stFindParam.iIndexPos - stFindParam.iOffset); // 毫米波雷达数据是图像数据的${dRatio}倍左右
		iEdPos = static_cast<int>(stFindParam.dRatio * stFindParam.iIndexPos + stFindParam.iOffset); // 毫米波雷达数据是图像数据的${dRatio}倍左右
	}
	
	iStPos = iStPos < 0 ? 0 : iStPos;
	iEdPos = iEdPos > static_cast<int>(iFolderSize) ? static_cast<int>(iFolderSize) : iEdPos;

	//LOG_DEBUG("timestamp: %llu, index: %u, start: %u, end: %u, size %u.", stFindParam.ui64Timestamp, stFindParam.iIndexPos, iStPos, iEdPos, vtFileInfo.size());

	// 升序排序,找到第一个在${ui32TimeSpan}时间差范围内的即可
	for (size_t i = static_cast<size_t>(iStPos); i < static_cast<size_t>(iEdPos); ++i)
	{
		if (stFindParam.iTimeSpan > abs(static_cast<int>(stFindParam.ui64Timestamp - vtFileInfo[i].ui64Timestamp)))
		{
			strPath = vtFileInfo[i].strPath;
			break;
		}
	}

	return strPath;
}

static std::string findRadarDataFilePath(size_t iIndexPos, uint64_t ui64Timestamp, size_t iSrcFolderSize, std::vector<FileAbsInfo> &vtFileInfo)
{
    size_t iDstFolderSize = vtFileInfo.size();
	FindParam stFindParam;
	stFindParam.bQueryAll = false;
	stFindParam.iSrcFolderSize = iSrcFolderSize;
	stFindParam.iIndexPos = iIndexPos;
	stFindParam.ui64Timestamp = ui64Timestamp;
	stFindParam.iOffset = 300;
	stFindParam.dRatio = (static_cast<double>(iDstFolderSize) * 1.0) / static_cast<double>(stFindParam.iSrcFolderSize);
	stFindParam.iTimeSpan = 45;

	std::string strPath = getRelateFilePath(stFindParam, vtFileInfo);
	if (strPath.empty())
	{
		// 如果第一次没有找到,进行全局查找
		stFindParam.bQueryAll = true;
		strPath = getRelateFilePath(stFindParam, vtFileInfo);

		// 如果第二次没有找到,再放大一次时间差范围进行查找,保障大部分能够找到
		if (strPath.empty())
		{
			stFindParam.iTimeSpan = 250;
			strPath = getRelateFilePath(stFindParam, vtFileInfo);
		}
	}

    return strPath;
}

void getFilePathsTest()
{
	std::string strFileFolder = "./data/images";
	std::vector<FileAbsInfo> vtFilePaths;
	getFilePaths(strFileFolder, vtFilePaths);

	std::string strFileRadarFolder = "./data/radars";
	std::vector<FileAbsInfo> vtFileRadarPaths;
	getFilePaths(strFileRadarFolder, vtFileRadarPaths);

	std::string strFileCanFolder = "./data/radars_can";
	std::vector<FileAbsInfo> vtFileCanPaths;
	getFilePaths(strFileCanFolder, vtFileCanPaths);

	size_t size = vtFilePaths.size();
	printf("file count : % d, % d, % d.\r\n", size, vtFileRadarPaths.size(), vtFileCanPaths.size());
	for (size_t i = 0; i < size; ++i)
	{
		std::string strRadar = findRadarDataFilePath(i, vtFilePaths.at(i).ui64Timestamp, size, vtFileRadarPaths);
		std::string strCan = findRadarDataFilePath(i, vtFilePaths.at(i).ui64Timestamp, size, vtFileCanPaths);
		
		if (!(strRadar.empty()) && !(strCan.empty()))
		{
#if 0
			printf("**************FOUND*************\r\n");
			printf("index: %d, file: %s, %llu.\r\n", i, vtFilePaths.at(i).strPath.data(), vtFilePaths.at(i).ui64Timestamp);
			printf("relate radar file: %s.\r\n", strRadar.data());
			printf("relate can file: %s.\r\n", strCan.data());
			printf("***************************\r\n");
#endif
		}
		else
		{
			printf("**************NOT FOUND*************\r\n");
			printf("index: %d, file: %s, %llu.\r\n", i, vtFilePaths.at(i).strPath.data(), vtFilePaths.at(i).ui64Timestamp);
			printf("relate radar file: %s.\r\n", strRadar.data());
			printf("relate can file: %s.\r\n", strCan.data());
			printf("***************************\r\n");
		}
	}

	return;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.NET(发音为“点 内特”)是由微软公司推出的一种软件开发框架。它包括了一系列的工具、类库和语言,可以帮助开发人员创建和运行各种类型的应用程序。 C#(发音为“C sharp”)是一种现代的面向对象的编程语言,是.NET框架的主要语言之一。C#结合了C++和Java的语法特点,提供了更简洁、更安全的编程体验。 使用.NET框架和C#语言,开发人员可以创建各种各样的应用程序,包括Web应用、桌面应用、移动应用和游戏等。它可以在Windows操作系统上运行,并且还可以通过Mono项目在其他平台上运行,如Linux和Mac。 .NET框架提供了许多功能强大的类库,这些类库可以大大简化开发过程。例如,它包括用于数据库访问、图形界面设计、网络编程和安全性等的类库。开发人员可以通过调用这些类库中的方法和属性来实现所需的功能,而无需从头开始编写代码。 C#语言具有面向对象的特性,这使得开发人员可以使用类和对象来组织代码,实现封装、继承和多态等概念。这样可以使代码更易读、易维护,并且提高代码的重用性。 总之,.NET框架和C#语言为开发人员提供了强大的工具和语言,使他们能够快速、高效地开发各种类型的应用程序。它们在业界广泛应用,并且有着庞大的开发者社区和资源支持。无论是初学者还是专业开发人员,都可以从中受益,并且轻松地构建出优秀的软件应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值