俺前段时间写了段功能相似的程序,但用的是用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函数:GetFileTimeulong 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给文件增加可执行的属性,那么文件的状态改变时间就会改变。
【答题不易,请采纳谢谢】