请我如何c语言遍历文件夹

请我如何c语言遍历文件夹,第1张

#include <windows.h>

/************************************************/

*参数说明:

char *pszDestPath为需要遍历的目标路径

/************************************************/

EnmuDirectory(char *pszDestPath)

{

//此结构说明参MSDN

WIN32_FIND_DATA FindFileData

//查找文件的句柄

HANDLE hListFile

//绝对路径,例:c:\windows\system32\cmd.exe

char szFullPath[MAX_PATH]

//相对路径

char szFilePath[MAX_PATH]

//构造相对路径

wsprintf(szFilePath, "%s\\*", pszDestPath)

//查找第一个文件,获得查找句柄,如果FindFirstFile返回INVALID_HANDLE_VALUE则返回

if((hListFile = FindFirstFile(szFilePath, &FindFileData)) == INVALID_HANDLE_VALUE)

{

//查找文件错误

return 1

}

else

{

do

{

//过滤.和..

//“.”代表本级目录“..”代表父级目录

if( lstrcmp(FindFileData.cFileName, TEXT(".")) == 0 ||

lstrcmp(FindFileData.cFileName, TEXT("..")) == 0 )

{

continue

}

//构造全路径

wsprintf(szFullPath, "%s\\%s", pszDestPath, FindFileData.cFileName)

//读取文件属性,如果不是文件夹

if(!(FindFileData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY))

{

//这里你可以自己添加分析是某种类型文件的代码。可以根据

//扩展名分析。

//这里有个实例,你可以看看

//有必要初始化一下

char *pszFileType = NULL

//把pszFileType指向cFileName的倒数第三个数符。因为一般扩展名长为3个字符。

//当然,你也可以用其它方法分析扩展名。或倒序查“.”

pszFileType = &(FindFileData.cFileName[strlen(FindFileData.cFileName) - 3])

//如果是jpg结尾的文件

if(!stricmp(pszFileType, "jpg"))

{

FILE *fp

//或许这里打开C:\\data.txt不应该用"w+",你可试着来

fp = fopen("c:\\data.txt", "w+")

if(fp) fputs(szFullPath, fp)

fclose(fp)

}

}

//如果是文件夹,则递归调用EnmuDirectory函数

if(FindFileData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)

{

EnmuDirectory(szFullPath)

}

//循环,查找下一个文件

}while(FindNextFile(hListFile, &FindFileData))

}

//关闭句柄

FindClose(hListFile)

//清空结构。可有可无的一句代码。函数退出会自动清空。

ZeroMemory(&FindFileData, sizeof(FindFileData))

return 0

}

这是windows api版的,还有MFC版的和C版的。要的话来找我Q:503267714

// FileScan.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include <filesystem>

#include <windows.h>

#define OK 0

#define ERR -1

#define TEST_FILE_MAX_SIZE "4.67G"

#define EXT_LEN 8

#define TYPE_LEN 8

#define DIR_MAX_LEN 260 //文件路径最多256个字符,加上D:\\

//ftell()返回int,最大2G 1<<32-1

typedef enum COND_VALUE

{

COND_VALUE_MORE = 0 ,//大于

COND_VALUE_LESS = 1 ,//小于

COND_VALUE_EUAQL = 2 ,//等于

COND_VALUE_MAX = 0xf

}COND_VALUE_E

typedef enum COND_TYPE

{

COND_TYPE_SIZE = 0 ,

COND_TYPE_CTIME = 1 ,

COND_TYPE_MTIME = 2,

COND_TYPE_EXTNAME = 4,

COND_TYPE_FILETYPE = 8,

COND_TYPE_MAX  = 0xf

}COND_TYPE_E

typedef struct COND_INFO

{

char cCondType : 4

char cCondValue : 4

}COND_INFO_S

typedef struct FILE_COND

{

//按照bit位来划分,前面四个bit位表示条件类型,后面四个bit位表示条件值

char cSymbol//用来标志大于或者小于,搜索时间,大小,类型,扩展名,属性

char szRes[ 3 ]//预留3个字节,四字节对齐

unsigned int uiSizeHigh//文件大小 高位

unsigned int uiSizeLow//低位

unsigned int uiCStartTime//创建时间

unsigned int uiCEndTime

unsigned int uiMStartTime//修改时间

unsigned int uiMEndTime

char szExtName[ EXT_LEN ]//扩展名

char szFileType[ TYPE_LEN ]//文件类型

unsigned int uiFileAttrib//文件属性

unsigned int uiFolderSizeHight//文件夹大小

unsigned int uiFolderSizeLow

}FILE_COND_S

//最大允许多少个条件搜索

#define CONDITION_MAX 4

FILE_COND_S g_astCond[ CONDITION_MAX ] = { 0 }

int g_iCondCnt = 0

int DisposeFile(char szFilePath[] , WIN32_FIND_DATA stWinFile)

{

DWORDLONG dwHighBase = MAXDWORD

dwHighBase += 1

DWORDLONG FileSize = stWinFile.nFileSizeHigh* dwHighBase + stWinFile.nFileSizeLow

printf("%s\\%s--Size:%lu\n" , szFilePath , stWinFile.cFileName , FileSize)

return OK

}

//转换字符串文件大小(如 45.67G)到int类型的文件大小

#define SECTION_CNT 2

#define MAX_NUM_DEC 100

#define UNIT_CNT 4

#define KB_OFFSET 10 //1KB == 1BIT<<10

#define MB_OFFSET 20

#define GB_OFFSET 30

#define TB_OFFSET 40

#define INT_OFFSET 32

int ConvertSizeStr2SizeLong(char szSizeStr[],unsigned int* puiSizeHigh,unsigned int* puiSizeLow)

{

int aNumSect[ SECTION_CNT ] = { 0 }//分别存整数位和小数位

//char sz = "..."

char acValidUint[UNIT_CNT] = { 'K' , 'M' , 'G' , 'T' }//数组

//char acValidUint[] = "KMGT"//字符串

char acOffset[ UNIT_CNT ] = { KB_OFFSET , MB_OFFSET , GB_OFFSET , TB_OFFSET }

char cOffset = 0

int iBaseNum

char* pcTmp

int index = 0

int i

int iMask

//入参判断

if (szSizeStr == NULL)

{

return ERR

}

pcTmp = szSizeStr

while (*pcTmp!=0)

{

if (*pcTmp == '.')

{

index++

if ( index >= SECTION_CNT )

{

return ERR

}

}

else if ( *pcTmp >= '0' && *pcTmp <= '9' )

{

//小数位取3位,剩余的舍去

if ( index == 1 && aNumSect[ index ] > MAX_NUM_DEC )

{

pcTmp++

continue

}

else if (index == 0 && aNumSect[index] > MAX_NUM_DEC)

{

//1234G 不合法,应该写成1.234T

return ERR

}

aNumSect[ index ] = aNumSect[ index ] * 10 + *pcTmp - '0'

}

else

for ( i = 0 i < UNIT_CNT++i )

{

if ( toupper(*pcTmp) == acValidUint[ i ] )

{

break

}

}

if (i == UNIT_CNT)

{

return ERR

}

}

pcTmp++

}

if (cOffset == 0)

{

*puiSizeHigh = 0

*puiSizeLow = aNumSect[ 0 ]

else

{

//先转为下一级单位

iBaseNum = ( aNumSect[ 0 ] << KB_OFFSET ) + aNumSect[ 0 ]//能保证小于MAX_UNIT

cOffset -= KB_OFFSET

}

iMask = ( 1 << cOffset ) - 1//用于取低于(INT_OFFSET - cOffset)数据

*puiSizeHigh = ( iBaseNum >> ( INT_OFFSET - cOffset ) ) & iMask

*puiSizeLow = iBaseNum << cOffset

return OK

}

//比较文件大小

int CompareFileSize(WIN32_FIND_DATA stWinFile , FILE_COND_S stCond,char cCondValue)

{

switch ( cCondValue )

{

case COND_VALUE_LESS:

{

if ( stWinFile.nFileSizeHigh > stCond.uiSizeHigh )

{

return ERR

}

else if ( stWinFile.nFileSizeHigh ==stCond.uiSizeHigh )

{

if ( stWinFile.nFileSizeLow > stCond.uiSizeLow )

{

return ERR

}

}

break

}

case COND_VALUE_MORE:

{

if ( stWinFile.nFileSizeHigh < stCond.uiSizeHigh )

{

return ERR

}

else if ( stWinFile.nFileSizeHigh == stCond.uiSizeHigh )

{

if ( stWinFile.nFileSizeLow < stCond.uiSizeLow )

{

return ERR

}

}

break

}

case COND_VALUE_EUAQL:

{

if ( stWinFile.nFileSizeHigh != stCond.uiSizeHigh || stWinFile.nFileSizeLow != stCond.uiSizeLow )

{

return ERR

}

break

}

default:

break

}

return OK

}

int CompareFileTime(WIN32_FIND_DATA stWinFile , FILE_COND_S stCond , char cCondValue)

{

return OK

}

int CheckCondition(char szFilePath[],WIN32_FIND_DATA stWinFile)

{

int i

int iCondType

int iCondValue

COND_INFO_S* pstCondInfo

for ( i = 0 i < g_iCondCnt ++i )

{

pstCondInfo = (COND_INFO_S*)(&( g_astCond[ i ].cSymbol))

switch (pstCondInfo->cCondType)

{

case COND_TYPE_SIZE:

{

if ( CompareFileSize(stWinFile , g_astCond[ i ],pstCondInfo->cCondValue) != OK )

{

return ERR

}

break

}

case COND_TYPE_CTIME:

{

if ( CompareFileTime(stWinFile , g_astCond[ i ] , pstCondInfo->cCondValue) != OK )

{

return ERR

}

break

}

//...

default:

break

}

}

return OK

}

int ScanDir(char szDir[])

{

if ( szDir == NULL )

{

return ERR

}

char szSubDir[ DIR_MAX_LEN ] = { 0 }

char szFind[ DIR_MAX_LEN ] = { 0 }

WIN32_FIND_DATA stWinFile

HANDLE hd

_snprintf_c(szFind , 

DIR_MAX_LEN , 

"%s\\*" ,

szDir)//两个反斜杠表示一个反斜杠转义符

hd = FindFirstFile(szFind , &stWinFile)//hd标志文件位置,用于查找下一个文件

if ( hd == INVALID_HANDLE_VALUE )

{

return ERR

}

while (1)

{

if (strcmp(stWinFile.cFileName,".") == 0 || strcmp(stWinFile.cFileName,"..") == 0)

{

//NULL

}

//判断是否是文件夹

else if ( stWinFile.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )

{

//清空szSubDir,因为在重新对szSubDir赋值时,是直接覆盖的,后者比当前保存的数据短,所以需要先清空再赋值

memset(szSubDir , 0 , DIR_MAX_LEN)

_snprintf_c(szSubDir , DIR_MAX_LEN , "%s\\%s" , szDir , stWinFile.cFileName)

ScanDir(szSubDir)//递归处理

}

else

{

if ( CheckCondition(szDir , stWinFile) == OK )

{

DisposeFile(szDir , stWinFile)

}

}

//查找下一个文件失败就跳出循环

if ( !FindNextFile(hd , &stWinFile) )

{

break

}

}

FindClose(hd)

return OK

}

int _tmain(int argc, _TCHAR* argv[])

{

COND_INFO_S stCond = { 0 }

COND_INFO_S* pstCond

char szDir[] = "C:"

stCond.cCondValue = COND_TYPE_SIZE

stCond.cCondValue = COND_VALUE_MORE

if (ConvertSizeStr2SizeLong(TEST_FILE_MAX_SIZE,&(g_astCond[0].uiSizeHigh),&(g_astCond[0].uiSizeLow)) == OK)

{

memcpy(&(g_astCond[ 0 ].cSymbol),&stCond,1)

pstCond = (COND_INFO_S*)( &g_astCond[ 0 ].cSymbol )

g_iCondCnt = 1

ScanDir(szDir)

}

system("pause")

return 0

}

看main函数和ScanDir函数。

ScanDir是一个递归函数。

这个要正对不同的 *** 作系统,不同的 *** 作系统,文件节点的存放方式不一样,读取的方式就不一样了。

可以利用for循环,像Linux

dir=opendir

(dirname)打开文件夹,返回目录指针,dp=readdir(dir)利用读目录,返回一行行读取目录的文件结构体指针,指针中存的有文件属性,是文件,还是文件夹。

通过判断是文件或者文件夹:

如果是文件,就就输出文件名dp->name

否则,就是一个文件夹

继续dir1=opendir(dp->name),dp1=readdir(dir1)..

一直循环到判断不到目录了。

windows应该也有类似的函数吧,这个我就么有用过了,你找找。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11622114.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存