C语言:如何得到指定地址的文件夹中所有文件的文件名和其修改时间 包括子文件内的

因为我要得到所有文件名然后用kmp算法模式匹配再按时间排序但是我不知道得到文件名和文件信息的语句windows下... 因为我要得到所有文件名 然后用kmp算法模式匹配 再按时间排序 但是我不知道得到文件名和文件信息的语句
windows下
展开
 我来答
sl65agm
2012-02-28 · TA获得超过1383个赞
知道小有建树答主
回答量:734
采纳率:0%
帮助的人:583万
展开全部

俺前段时间写了段功能相似的程序,但用的是用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配合使用。
斯坦恩贝格(北京)电子有限公司
2015-09-15 · 斯坦恩贝格生产销售“希曼顿”牌固态继电器、电力调整器,温控器
斯坦恩贝格(北京)电子有限公司
斯坦恩贝格生产销售“希曼顿”牌固态继电器、电力调整器,温控器
向TA提问
展开全部
//获取指定目录下的所有文件列表 author:wangchangshaui jlu
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;
}
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
zhouciming
2012-02-27 · TA获得超过223个赞
知道小有建树答主
回答量:393
采纳率:0%
帮助的人:156万
展开全部
windows下和linux下可是有很大区别的噢。
追问
windows下
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式