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

Python018

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

俺前段时间写了段功能相似的程序,但用的是用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)

}

}

测试结果如图所示。

用api函数:GetFileTime

ulong hfile

long rtn

filetime lpcreate

filetime lpaccess

filetime lpwrite

hfile = FileOpen("odbc.ini")

rtn = GetFileTime(hfile, lpcreate, lpaccess, lpwrite)

Messagebox("File Handle", String(hfile))

Messagebox("Return Code", string(rtn))

FileClose(hfile)

在 Windows 下,一个文件有创建时间、修改时间、访问时间。而在 Linux 下,一个文件也有三种时间,分别是访问时间(Access)、修改时间(Modify)、状态改变时间(Change)。

可以使用 stat 命令查看文件的访问时间、修改时间和状态改变时间。

很不幸,Linux 目前常见的文件系统是没有存储文件创建时间的,比如 ext3 就没有存储。但是有些文件系统是有的,尽管它们为创建时间使用的字段名称是不一样的,比如:

ufs2 ->st_birthtime zfs ->crtime ext4 ->crtime btrfs ->otime jfs ->di_otime

那么如何查看我们的文件系统呢?可以使用 df -T 命令来查看磁盘各个分区使用的文件系统类型。

本人使用的机器的磁盘分区使用的文件系统类型是 ext3,也就是说本人是无法查看文件创建时间的。但是,如果文件创建后就没有修改过,修改时间=创建时间;如果文件创建后,状态就没有改变过,那么状态改变时间=创建时间;如果文件创建后,没有被读取过,那么访问时间=创建时间,当这个基本不太可能。

那什么时候访问时间,修改时间和状态改变时间会变化呢?比如我们使用vi打开文件但不编辑,那么退出后文件的访问时间就会改变;比如我们使用vi打开文件并且编辑后保存退出,那么文件的修改时间就会改变,当然访问时间也改变了;再比如使用chmod +x给文件增加可执行的属性,那么文件的状态改变时间就会改变。

【答题不易,请采纳谢谢】