C语言:如何得到指定地址的文件夹中所有文件的文件名和其修改时间 包括子文件内的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言:如何得到指定地址的文件夹中所有文件的文件名和其修改时间 包括子文件内的相关的知识,希望对你有一定的参考价值。
因为我要得到所有文件名 然后用kmp算法模式匹配 再按时间排序 但是我不知道得到文件名和文件信息的语句
windows下
俺前段时间写了段功能相似的程序,但用的是用C++/STL写的,访问目录使用了win32 api(能访问指定目录的子目录)。
获取文件名与修改时间由FileOfDirectory::detectFiles实现(其实你只需要看这一个函数即可)。
这段程序以STL数组保存单个文件名,查询过程中没有回溯,wcsstr函数内部也是KMP,所以事实上这个程序也是按KMP查询的
安时间排序时使用STL算法库,时间复杂度同快速排序。
最后,这段代码是在VS2010编译的。
# include <vector>
# include <algorithm>
struct FileNameAndTime
wchar_t szPath[MAX_PATH]; //file directory
wchar_t szName[MAX_PATH]; //file name
FILETIME lastAcc; //last access time
FileNameAndTime()
memset(&lastAcc, 0, sizeof(lastAcc));
memset(szName, 0, sizeof(wchar_t) * MAX_PATH);
memset(szPath, 0, sizeof(wchar_t) * MAX_PATH);
FileNameAndTime(const PWCHAR fn, const PWCHAR pa, const LPFILETIME ft)
if( (0 == fn) || (0 == pa) || (0 == ft) )
return;
memcpy(&lastAcc, ft, sizeof(lastAcc));
wcscpy(szName, fn);
wcscpy(szPath, pa);
FileNameAndTime(const FileNameAndTime& fnd)
memcpy(&this->lastAcc, &fnd.lastAcc, sizeof(this->lastAcc));
wcscpy(this->szName, fnd.szName);
wcscpy(this->szPath, fnd.szPath);
const FileNameAndTime& operator=(const FileNameAndTime& fnd)
if(this != &fnd)
memcpy(&this->lastAcc, &fnd.lastAcc, sizeof(this->lastAcc));
wcscpy(this->szName, fnd.szName);
wcscpy(this->szPath, fnd.szPath);
return *this;
void GetFullPath( wchar_t (&fp)[MAX_PATH] ) const
wcscpy(fp, szPath);
wcscat(fp, szName);
friend bool operator>(const FileNameAndTime& l, const FileNameAndTime& r); //compare this object by access time
;
bool operator<(const FileNameAndTime& l, const FileNameAndTime& r) //for sort
if(l.lastAcc.dwHighDateTime < r.lastAcc.dwHighDateTime)
return true;
else if (l.lastAcc.dwHighDateTime == r.lastAcc.dwHighDateTime)
if(l.lastAcc.dwLowDateTime < r.lastAcc.dwLowDateTime)
return true;
return false;
class FileOfDirectory
private:
static const wchar_t szDot[];
static const wchar_t szDotDot[];
static const wchar_t cStar;
static const wchar_t cSlash;
private:
std::vector<FileNameAndTime> vecFT;
wchar_t szCurrentPath[MAX_PATH];
private:
void validatePath(const wchar_t* pPath)
wcscpy(szCurrentPath, pPath);
int len = wcslen(szCurrentPath);
if( (cStar != szCurrentPath[len - 1])
&& (cSlash != szCurrentPath[len - 2]) )
szCurrentPath[len] = cSlash;
szCurrentPath[len + 1] = cStar;
szCurrentPath[len + 2] = 0;
return;
if( (cStar != szCurrentPath[len - 1])
&& (cSlash == szCurrentPath[len - 2]) )
szCurrentPath[len] = cStar;
szCurrentPath[len + 1] = 0;
return;
void detectFiles(const LPWSTR szDir)
WIN32_FIND_DATA ffd;
HANDLE hFind = ::FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind)
return ;
do
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
if( (0 == wcscmp(ffd.cFileName, szDot)) || (0 == wcscmp(ffd.cFileName, szDotDot)))
continue;
else
wchar_t szTempPath[MAX_PATH];
wcscpy(szTempPath, szDir);
szTempPath[wcslen(szTempPath) - 1] = 0;
wcscat(szTempPath, ffd.cFileName);
int len = wcslen(szTempPath);
szTempPath[len] = cSlash;
szTempPath[len + 1] = cStar;
szTempPath[len + 2] = 0;
detectFiles(szTempPath);
else
wchar_t path[MAX_PATH];
wcscpy(path, szDir);
path[wcslen(path) - 1] = 0;
vecFT.push_back(FileNameAndTime(ffd.cFileName,path, &ffd.ftLastAccessTime));
while (::FindNextFile(hFind, &ffd) != 0);
public:
FileOfDirectory(const LPWSTR szDir)
validatePath(szDir);
detectFiles(szCurrentPath);
void SortByAccessTime()
sort(vecFT.begin(), vecFT.end());
int NumOfFiles() const return vecFT.size();
int FindFilesByKeyWord(wchar_t* pszFn, int* outCome, int outComeLen, bool bMatchAll = false)
wchar_t szTemp[MAX_PATH], szFnLwr[MAX_PATH];
int index = 0;
wcscpy(szFnLwr, pszFn);
_wcslwr(szFnLwr);
for(int i = 0; i < vecFT.size(); ++i)
wcscpy(szTemp, vecFT[i].szName);
_wcslwr(szTemp);
if(true == bMatchAll)
if(0 == wcscmp(szTemp, szFnLwr))
if(index >= outComeLen)
return index;
outCome[index++] = i;
else
if(0 != wcsstr(szTemp, szFnLwr))
if(index >= outComeLen)
return index;
outCome[index++] = i;
FileNameAndTime GetItemByID(int index)
if( (index >= 0) && (index < vecFT.size()) )
return FileNameAndTime(vecFT[index]);
;
const wchar_t FileOfDirectory::szDot[] = L".";
const wchar_t FileOfDirectory::szDotDot[] = L"..";
const wchar_t FileOfDirectory::cStar = L'*';
const wchar_t FileOfDirectory::cSlash = L'\\\\';
void __stdcall entp3() //测试程序
FileOfDirectory fod(L"E:\\\\game");
int ids[256] = 0 ;
fod.SortByAccessTime();
int len = fod.FindFilesByKeyWord(L"main", ids, 256);
for(int i = 0; i <len; ++i)
FileNameAndTime fnt(fod.GetItemByID(ids[i]));
CDbgString::OutputDbgStringW(L"\\r\\n%s%s", fnt.szPath, fnt.szName);
测试结果如图所示。
追问我在vs2010下编译不了 为什么没有main主函数 还看不太懂class FileOfDirectory
追答哦,俺也用的是vs2010,这个要设置一下才能不写main。
项目名-右键-属性-链接器-子系统:改为未设置
项目名-右键-属性-链接器-高级:输入entp3就能通过编译。
你也可以不改项目属性。
如果你写控制台程序,把entp3的代码写到main里即可,如果是windows程序,写到WinMain里即可。
当然你可以在自己的main函数中用FileOfDirectory类。
FileOfDirectory中:
validatePath用于修改路径的,比如你想枚举出c:\abc下所有的文件与文件夹,函数FindFirstFile要求你输入c:\abc\*才行。
detectFiles是得到目录下所有文件的,通过递归扫描子目录。
SortByAccessTime是按修改时间排序文件的,因为先搜索近期用过的文件意义比较大。
int FindFilesByKeyWord(wchar_t* pszFn, int* outCome, int outComeLen, bool bMatchAll = false)用于搜索指定文件,可以返回所有符合条件的文件名索引。pszFn是关键字,数组outCome用于存放搜索到的文件的索引,outComeLen是数组outCome的长度,bMatchAll = true表示必须和关键字全部匹配才能返回,反之只要文件名中包含关键就可返回。
GetItemByID更具索引返回FileNameAndTime 对象,一般和FindFilesByKeyWord配合使用。
char** getFileNameArray(const char *path, int* fileCount)
int count = 0;
char **fileNameList = NULL;
struct dirent* ent = NULL;
DIR *pDir;
char dir[512];
struct stat statbuf;
//打开目录
if ((pDir = opendir(path)) == NULL)
myLog("Cannot open directory:%s\n", path);
return NULL;
//读取目录
while ((ent = readdir(pDir)) != NULL)
//统计当前文件夹下有多少文件(不包括文件夹)
//得到读取文件的绝对路径名
snprintf(dir, 512, "%s/%s", path, ent->d_name);
//得到文件信息
lstat(dir, &statbuf);
//判断是目录还是文件
if (!S_ISDIR(statbuf.st_mode))
count++;
//while
//关闭目录
closedir(pDir);
// myLog("共%d个文件\n", count);
//开辟字符指针数组,用于下一步的开辟容纳文件名字符串的空间
if ((fileNameList = (char**) myMalloc(sizeof(char*) * count)) == NULL)
myLog("Malloc heap failed!\n");
return NULL;
//打开目录
if ((pDir = opendir(path)) == NULL)
myLog("Cannot open directory:%s\n", path);
return NULL;
//读取目录
int i;
for (i = 0; (ent = readdir(pDir)) != NULL && i < count;)
if (strlen(ent->d_name) <= 0)
continue;
//得到读取文件的绝对路径名
snprintf(dir, 512, "%s/%s", path, ent->d_name);
//得到文件信息
lstat(dir, &statbuf);
//判断是目录还是文件
if (!S_ISDIR(statbuf.st_mode))
if ((fileNameList[i] = (char*) myMalloc(strlen(ent->d_name) + 1))
== NULL)
myLog("Malloc heap failed!\n");
return NULL;
memset(fileNameList[i], 0, strlen(ent->d_name) + 1);
strcpy(fileNameList[i], ent->d_name);
myLog("第%d个文件:%s\n", i, ent->d_name);
i++;
//for
//关闭目录
closedir(pDir);
*fileCount = count;
return fileNameList;
参考技术B windows下和linux下可是有很大区别的噢。追问
windows下
易语言 如何 列出 指定目录下 所有 文件名
@ECHO OFFFOR /F "tokens=1,2" %%a IN (city.txt) DO (
IF EXIST %%a% %.txt (
COPY %%a% %.txt %%b% %.txt
)
)
这是从别人那边转过来的。我不大懂这个东西。
以下内容来自
dir /a/b 指定目录路径 >输出目录路径\1.txt
如果输出路径为%ComputerName%.txt则命名为计算机名
新建文本文档在文本文档里输入:
dir *.* /a /b /s >1.txt
保存为 提取名字.bat
文件名字被提取到当前文件夹的1.txt里面了!也可以提取某类型的文件比如*.mp3 或者a*.mp3
参 数:
-1 每列仅显示一个文件或目录名称。
-a或--all 下所有文件和目录。
-A或--almost-all 显示所有文件和目录,但不显示现行目录和上层目录。
-b或--escape 显示脱离字符。
-B或--ignore-backups 忽略备份文件和目录。
-c 以更改时间排序,显示文件和目录。
-C 以又上至下,从左到右的直行方式显示文件和目录名称。
-d或--directory 显示目录名称而非其内容。
-D或--dired 用Emacs的模式产生文件和目录列表。
-f 此参数的效果和同时指定"aU"参数相同,并关闭"lst"参数的效果。
-F或--classify 在执行文件,目录,Socket,符号连接,管道名称后面,各自加上"*","/","=","@","|"号。
-g 次参数将忽略不予处理。
-G或--no-group 不显示群组名称。
-h或--human-readable 用"K","M","G"来显示文件和目录的大小。
-H或--si 此参数的效果和指定"-h"参数类似,但计算单位是1000Bytes而非1024Bytes。
-i或--inode 显示文件和目录的inode编号。
-I<范本样式>或--ignore=<范本样式> 不显示符合范本样式的文件或目录名称。
-k或--kilobytes 此参数的效果和指定"block-size=1024"参数相同。
-l 使用详细格式列表。
-L或--dereference 如遇到性质为符号连接的文件或目录,直接列出该连接所指向的原始文件或目录。
-m 用","号区隔每个文件和目录的名称。
-n或--numeric-uid-gid 以用户识别码和群组识别码替代其名称。
-N或--literal 直接列出文件和目录名称,包括控制字符。
-o 此参数的效果和指定"-l" 参数类似,但不列出群组名称或识别码。
-p或--file-type 此参数的效果和指定"-F"参数类似,但不会在执行文件名称后面加上"*"号。
-q或--hide-control-chars 用"?"号取代控制字符,列出文件和目录名称。
-Q或--quote-name 把文件和目录名称以""号标示起来。
-r或--reverse 反向排序。
-R或--recursive 递归处理,将指定目录下的所有文件及子目录一并处理。
-s或--size 显示文件和目录的大小,以区块为单位。
-S 用文件和目录的大小排序。
-t 用文件和目录的更改时间排序。
-T<跳格字符>或--tabsize=<跳格字数> 设置跳格字符所对应的空白字符数。
-u 以最后存取时间排序,显示文件和目录。
-U 列出文件和目录名称时不予排序。
-v 文件和目录的名称列表以版本进行排序。
-w<每列字符数>或--width=<每列字符数> 设置每列的最大字符数。
-x 以从左到右,由上至下的横列方式显示文件和目录名称。
-X 以文件和目录的最后一个扩展名排序。
--block-size=<区块大小> 指定存放文件的区块大小。
--color=<列表格式> 培植文件和目录的列表格式。
--full-time 列出完整的日期与时间。
--help 在线帮助。
--indicator-style=<标注样式> 在文件和目录等名称后面加上标注,易于辨识该名称所属的类型。
--quoting-syte=<引号样式> 把文件和目录名称以指定的引号样式标示起来。
--show-control-chars 在文件和目录列表时,使用控制字符。
--sort=<排序方式> 配置文件和目录列表的排序方式。
--time=<时间戳记> 用指定的时间戳记取代更改时间。
--version 显示版本信息。
批量重命名
新建文本文档在文本文档里输入:
@for /f %%a in (A.txt) do @(
if exist %%a for /f %%b in (B.txt) do (
rename %%a %%b))
保存为 批量改名.bat
A.txt 是原来的文件名
B.txt 是修改后的文件名
一行对应一个名字不能有空格同时注意文件属性
a.txt :
NBA直播录像1.3gp
NBA直播录像2.3gp
NBA直播录像3.3gp
NBA直播录像4.3gp
b.txt :
NBA直播录像第一场.3gp
NBA直播录像第二场.3gp
NBA直播录像第三场.3gp
NBA直播录像第四场.3gp
参考技术A 一个简单的、、、
.版本 2
.支持库 EThread
.程序集 窗口程序集1
.程序集变量 是否停止, 逻辑型
.程序集变量 列表框文件名, 文本型, , "0"
.子程序 __启动窗口_创建完毕
编辑框1.内容 = 取运行目录 () + “\”
组合框1.加入项目 (“*”, )
组合框1.加入项目 (“exe”, )
组合框1.加入项目 (“jpg”, )
组合框1.加入项目 (“bmp”, )
组合框1.现行选中项 = 0
.子程序 _按钮1_被单击
是否停止 = 假
启动线程 (&子程序1, , )
.子程序 子程序1
.局部变量 表项
.局部变量 路径, 文本型
.局部变量 文件名, 文本型
.如果真 (是否停止 = 真) ' 搜索被停止,则返回
返回 ()
.如果真结束
文件名 = 寻找文件 (编辑框1.内容 + 组合框1.内容, )
.判断循环首 (文件名 ≠ “”) ' 显示找到的文件
列表框1.加入项目 (文件名, )
加入成员 (列表框文件名, 编辑框1.内容 + 文件名)
文件名 = 寻找文件 (, )
.判断循环尾 ()
.子程序 _按钮2_被单击
是否停止 = 真 参考技术B 判断循环首(返回文件名!="")
返回文件名=寻找文件(“D:\*.*”,)
列表框。添加项目还是什么(记不太清楚了)=“D:\”+返回文件名
判断循环尾
按照这个伪码自己去试一下吧~应该能做出的!!
以上是关于C语言:如何得到指定地址的文件夹中所有文件的文件名和其修改时间 包括子文件内的的主要内容,如果未能解决你的问题,请参考以下文章
c语言怎样读取指定RAM存储单元的数据出来 比如我要读取0XF0 RAM地址的值应如何实现.