?? 文件夾時(shí)間屬性的獲取與更改.txt
字號(hào):
VC++實(shí)現(xiàn)文件夾時(shí)間屬性的獲取與更改
引言:
對(duì)于大多數(shù)的IT企業(yè)和絕大多數(shù)的個(gè)人用戶而言,數(shù)據(jù)的備份主要是對(duì)數(shù)據(jù)內(nèi)容的簡(jiǎn)單備份,而很少涉及對(duì)備份數(shù)據(jù)自身屬性如文件屬性、所在文件夾的時(shí)間屬性等內(nèi)容的備份。而在某些對(duì)數(shù)據(jù)管理有著非常嚴(yán)格要求的特殊行業(yè)中,對(duì)以上這些相關(guān)屬性信息的備份也是同等重要的。
但是在目前的Windows操作系統(tǒng)下,不論是直接通過(guò)手工進(jìn)行數(shù)據(jù)備份還是通過(guò)某些數(shù)據(jù)備份軟件來(lái)進(jìn)行,都難以將這些信息完全保持原貌復(fù)制過(guò)來(lái),尤其對(duì)于每時(shí)每刻均在發(fā)生變化的時(shí)間屬性更是難以保持其原始信息。不僅如此,在Windows操作系統(tǒng)下甚至沒(méi)有提供能直接修改此類屬性的工具和手段。為此,筆者對(duì)該問(wèn)題做了研究,并總結(jié)出一套比較簡(jiǎn)單的解決辦法。其中,對(duì)于文件屬性的備份與更改方法筆者已在電腦報(bào)天極網(wǎng)《在VC++下對(duì)文件屬性的獲取與更改》一文做了闡述,因此,本文在此就不再加以贅述,而著重對(duì)文件夾時(shí)間屬性的獲取與更改方法進(jìn)行介紹。
設(shè)計(jì)思路
在Windows操作系統(tǒng)下并沒(méi)有提供任何可供修改文件夾時(shí)間屬性的方法和手段,即使是在Win32 API函數(shù)中,也只是提供了對(duì)文件時(shí)間屬性進(jìn)行修改的函數(shù)調(diào)用,而沒(méi)有關(guān)于文件夾時(shí)間屬性修改的只言片語(yǔ)。雖然Windows所提供的備份程序能夠把待備份文件夾下的所有子文件夾的時(shí)間屬性按照原樣完整的復(fù)制過(guò)去,但是卻無(wú)法保持根目錄時(shí)間屬性的恒定。由此,可以考慮采取備份的方式來(lái)進(jìn)行,并從同備份相關(guān)的Win32 API函數(shù)入手。具體而言,可以先以打開(kāi)文件的方式來(lái)打開(kāi)文件夾,然后就可以通過(guò)原本用于處理文件時(shí)間屬性的Win32 API函數(shù)GetFileTime()和SetFileTime()來(lái)獲取原始時(shí)間屬性并以其為參數(shù)來(lái)設(shè)置備份后的文件夾時(shí)間屬性了,這樣的處理可以確保文件夾在備份前后時(shí)間屬性的一致。
根據(jù)前面的分析可以看出,按照打開(kāi)文件的方式來(lái)打開(kāi)文件夾是整個(gè)處理過(guò)程的關(guān)鍵,通常主要用于創(chuàng)建、打開(kāi)文件的Win32 API函數(shù)CreateFile()并非只能用來(lái)創(chuàng)建和打開(kāi)文件對(duì)象,實(shí)際上它還可以用來(lái)創(chuàng)建、打開(kāi)管道、郵槽、通訊資源、磁盤(pán)驅(qū)動(dòng)器(只對(duì)Windows NT而言)、控制臺(tái)和文件夾(只能打開(kāi))等。下面給出CreateFile()的原型:
HANDLE CreateFile( LPCTSTR lpFileName, // 文件名指針
DWORD dwDesiredAccess, // 訪問(wèn)模式
DWORD dwShareMode, // 共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //安全屬性
DWORD dwCreationDisposition, // 創(chuàng)建方式
DWORD dwFlagsAndAttributes, // 文件屬性
HANDLE hTemplateFile // 指向待復(fù)制屬性的文件指針
);
當(dāng)用其進(jìn)行文件夾打開(kāi)操作時(shí),第一個(gè)參數(shù)lpFileName應(yīng)被設(shè)置成為待打開(kāi)的文件夾的名稱;至于訪問(wèn)模式可以根據(jù)需要靈活設(shè)置,對(duì)于本文而言,對(duì)源文件夾只進(jìn)行讀取操作故可以設(shè)置為GENERIC_READ,對(duì)于備份后的文件夾由于需要將屬性信息寫(xiě)入,因此需要有GENERIC_WRITE的支持;共享模式參數(shù)dwShareMode的設(shè)置與進(jìn)行文件處理時(shí)的設(shè)置沒(méi)有什么區(qū)別,在此可以設(shè)置為FILE_SHARE_READ|FILE_SHARE_DELETE;由于CreateFile()函數(shù)在進(jìn)行文件夾操作時(shí),不能以創(chuàng)建方式進(jìn)行,因此創(chuàng)建方式只能打開(kāi)已經(jīng)存在的對(duì)象,即dwCreationDisposition應(yīng)當(dāng)設(shè)置為OPEN_EXISTING;相比而言,dwFlagsAndAttributes參數(shù)的設(shè)置是比較重要的,正是通過(guò)將該參數(shù)設(shè)置為FILE_FLAG_BACKUP_SEMANTICS屬性才使CreateFile()函數(shù)來(lái)進(jìn)行打開(kāi)文件夾的操作。
通常,文件、文件夾的時(shí)間屬性指的是創(chuàng)建時(shí)間、最近訪問(wèn)時(shí)間和最近修改時(shí)間等幾個(gè)具體屬性。對(duì)于文件的上述屬性可以通過(guò)GetFileTime()來(lái)獲取,對(duì)于文件夾,在通過(guò)CreateFile()函數(shù)將其打開(kāi)后,其獲取得到的句柄可以當(dāng)作文件句柄來(lái)使用。因此,通過(guò)GetFileTime()函數(shù)同樣也可以得到文件夾的時(shí)間屬性。GetFileTime()函數(shù)原型如下:
BOOL GetFileTime( HANDLE hFile, // 文件句柄
LPFILETIME lpCreationTime, // 創(chuàng)建時(shí)間的地址
LPFILETIME lpLastAccessTime, // 最近訪問(wèn)時(shí)間的地址
LPFILETIME lpLastWriteTime // 最近修改時(shí)間的地址
);
其中后三個(gè)參數(shù)均是指向FILETIME結(jié)構(gòu)的指針,得到的也都是UTC時(shí)間,如果需要,可以通過(guò)FileTimeToLocalFileTime()函數(shù)將此UTC時(shí)間轉(zhuǎn)化成本地時(shí)間。而且還可以進(jìn)一步通過(guò)FileTimeToSystemTime()函數(shù)將其從文件時(shí)間格式轉(zhuǎn)化成系統(tǒng)時(shí)間格式,轉(zhuǎn)化后的時(shí)間格式將保存在一個(gè)SYSTEMTIME結(jié)構(gòu)對(duì)象中。類似的,在將時(shí)間信息寫(xiě)入到文件夾屬性時(shí),如果不是文件時(shí)間格式也應(yīng)當(dāng)通過(guò)SystemTimeToFileTime()函數(shù)將其從系統(tǒng)時(shí)間格式轉(zhuǎn)換成文件時(shí)間格式,然后再通過(guò)SetFileTime()函數(shù)將指定的時(shí)間寫(xiě)入到文件夾的時(shí)間屬性中去。這樣,在進(jìn)行數(shù)據(jù)備份和恢復(fù)的過(guò)程中,包括根目錄在內(nèi)的所有文件夾都可以保持時(shí)間屬性的一致。
簡(jiǎn)單示例
下面根據(jù)前面的講述而給出一個(gè)簡(jiǎn)單的應(yīng)用示例,通過(guò)此示例可以從指定的文件夾讀取時(shí)間屬性信息并可在經(jīng)過(guò)修改后再回寫(xiě)進(jìn)去(在此僅對(duì)最近修改時(shí)間進(jìn)行處理,對(duì)于其他的時(shí)間屬性可用類似的方法加以實(shí)現(xiàn))。這里通過(guò)兩個(gè)函數(shù)GetDirTime()和SetDirTime()來(lái)實(shí)現(xiàn)對(duì)文件夾時(shí)間信息的獲取與更改處理,下面就以注釋的形式對(duì)這兩個(gè)函數(shù)的實(shí)現(xiàn)過(guò)程進(jìn)行講解:
// 獲取指定文件夾的時(shí)間屬性,入口參數(shù)DirName指定了待處理的文件夾,stime為一
// 指向SYSTEMTIME結(jié)構(gòu)的指針
BOOL CSetForderTimeDlg::GetDirTime(CString DirName, SYSTEMTIME &stime){
// 打開(kāi)文件夾
HANDLE hDir = CreateFile (DirName, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_DELETE,
NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
FILETIME lpCreationTime; // 文件夾的創(chuàng)建時(shí)間
FILETIME lpLastAccessTime; // 對(duì)文件夾的最近訪問(wèn)時(shí)間
FILETIME lpLastWriteTime; // 文件夾的最近修改時(shí)間
// 獲取文件夾時(shí)間屬性信息
if (GetFileTime(hDir, &lpCreationTime, &lpLastAccessTime, &lpLastWriteTime)){
FILETIME ftime;
FileTimeToLocalFileTime(&lpLastWriteTime, &ftime); // 轉(zhuǎn)換成本地時(shí)間
FileTimeToSystemTime(&ftime, &stime); // 轉(zhuǎn)換成系統(tǒng)時(shí)間格式
}
CloseHandle(hDir); // 關(guān)閉打開(kāi)過(guò)的文件夾
return retval;
}
// 設(shè)置指定文件夾的時(shí)間屬性,入口參數(shù)DirName指定了待處理的文件夾,new_time
// 為一指向SYSTEMTIME結(jié)構(gòu)的指針
BOOL CSetForderTimeDlg::SetDirTime(CString DirName, SYSTEMTIME new_stime){
// 打開(kāi)目錄的Win32 API調(diào)用
HANDLE hDir = CreateFile(DirName, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_DELETE,
NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
FILETIME lpCreationTime; // 文件夾的創(chuàng)建時(shí)間
FILETIME lpLastAccessTime; // 對(duì)文件夾的最近訪問(wèn)時(shí)間
FILETIME lpLastWriteTime; // 對(duì)文件夾的最近修改時(shí)間
SystemTimeToFileTime(&new_stime, &lpCreationTime); // 轉(zhuǎn)換成文件時(shí)間格式
SystemTimeToFileTime(&new_stime, &lpLastAccessTime);
SystemTimeToFileTime(&new_stime, &lpLastWriteTime);
// 設(shè)置文件夾的時(shí)間屬性
BOOL retval = SetFileTime(hDir, &lpCreationTime, &lpLastAccessTime, &lpLastWriteTime);
CloseHandle(hDir); // 關(guān)閉文件夾
return retval;
}
至此,可以很方便的通過(guò)調(diào)用GetDirTime()和SetDirTime()函數(shù)來(lái)實(shí)現(xiàn)對(duì)任意指定文件夾時(shí)間屬性的獲取與設(shè)置,具體為:
SYSTEMTIME stime; // 系統(tǒng)時(shí)間結(jié)構(gòu)對(duì)象
if (GetDirTime(m_Path, stime))
{
// 如果獲取文件夾時(shí)間屬性成功,獲取到的時(shí)間信息將保存在stime結(jié)構(gòu)對(duì)象中
……
// 如果需要可以對(duì)獲取到的時(shí)間屬性進(jìn)行修改,也可以保留不變
……
// 將修改后的時(shí)間屬性回寫(xiě)到文件夾
SetDirTime(m_Path, stime);
}
小結(jié)
本文通過(guò)CreateFile()函數(shù)打開(kāi)文件夾,并在以后的處理中將其以文件來(lái)對(duì)待,從而可以使用GetFileTime()、SetFileTime()等函數(shù)來(lái)對(duì)其時(shí)間屬性進(jìn)行獲取與寫(xiě)入處理,可對(duì)包括根目錄在內(nèi)的任意文件夾進(jìn)行時(shí)間屬性設(shè)置。在數(shù)據(jù)的完整備份與復(fù)原等方面中有較好的應(yīng)用前景。本文所述代碼在Windows 2000 Professional下,由Microsoft Visual C++ 6.0編譯通過(guò)。
信息標(biāo)題:VC編程改變指定的文件或文件夾的屬性
發(fā)布人:網(wǎng)絡(luò)無(wú)名
發(fā)布日期:2007-4-4
瀏覽次數(shù):64
VC編程改變指定的文件或文件夾的屬性
來(lái)源:邪惡八進(jìn)制
文件是數(shù)據(jù)在磁盤(pán)上最常用的一種存放形式,也是在程序設(shè)計(jì)中與之經(jīng)常打交道的一種編程對(duì)象,不少程序尤其是數(shù)據(jù)傳輸和處理類的應(yīng)用程序更是需要頻繁的創(chuàng)建、讀取和寫(xiě)入文件。對(duì)于一些要求不是很嚴(yán)格的程序,我們往往只關(guān)心文件的內(nèi)容是否正確、文件大小是否有增減或是再嚴(yán)格一些,看文件名是否符合規(guī)定等等。以上這些要素對(duì)于大多數(shù)程序而言顯然是可以滿足實(shí)際需求的,但對(duì)于某些特殊行業(yè)的一些有著比較嚴(yán)格要求的軟件系統(tǒng),僅有以上要素還是遠(yuǎn)遠(yuǎn)不夠的,往往還需要對(duì)文件的所有屬性諸如文件的創(chuàng)建時(shí)間、文件的最后訪問(wèn)時(shí)間、文件的最后修改時(shí)間、文件的讀寫(xiě)、文件的隱現(xiàn)等等進(jìn)行提取處理與重新設(shè)置。例如,修改文件的讀寫(xiě)隱現(xiàn)等屬性,可以實(shí)現(xiàn)文件的保護(hù)和控制,尤其是修改文件的產(chǎn)生修改和訪問(wèn)時(shí)間,可以避免因防病毒更改系統(tǒng)時(shí)間而造成的文件修改時(shí)間的紊亂所形成的不便。在DOS下文件的屬性可以用DOS命令加以修改,在WINDOWS下,可以通過(guò)右鍵的屬性改變一組文件和文件夾的讀寫(xiě)屬性,但是卻不能修改文件的產(chǎn)生修改和訪問(wèn)時(shí)間,并且不能修改子目錄下的文件和文件夾的屬性。
本實(shí)例基于Windows的API,設(shè)計(jì)了通用的文件和文件夾的屬性(包括文件的產(chǎn)生修改和訪問(wèn)時(shí)間以及讀寫(xiě)隱現(xiàn)等)的修改方法,并實(shí)現(xiàn)了其Visual C++程序編碼。程序運(yùn)行后,點(diǎn)擊"修改屬性"按鈕,就可以將項(xiàng)目文件夾中的"2.doc"文檔的屬性修改的與"1.doc"文檔一致。
一、實(shí)現(xiàn)方法
關(guān)于文件的全部屬性信息,總計(jì)有以下以下9種:文件的標(biāo)題名、文件的屬性(只讀、存檔,隱藏等)、文件的創(chuàng)建時(shí)間、文件的最后訪問(wèn)時(shí)間、文件的最后修改時(shí)間、文件大小的高位雙字、文件大小的低位雙字、保留、保留。在這里只有文件標(biāo)題名和文件的長(zhǎng)度可以通過(guò)CFile類比較方便的獲得,而對(duì)于其他幾種屬性的獲取和設(shè)置就無(wú)能為力了。
Windows中的API函數(shù)組提供了用于文件讀寫(xiě)、屬性設(shè)置的眾多API函數(shù),例如:
HANDLE CreateFile( LPCTSTR, DWORD, DWORD,LPSECURITY_ATTRIBUTES, DWORD,DWORD,HANDLE );
該函數(shù)產(chǎn)生或者打開(kāi)一個(gè)系統(tǒng)對(duì)象,并返回一個(gè)用以訪問(wèn)該對(duì)象的句柄,這些對(duì)象可以是文件、文件夾、管道等。
HANDLE FindFirstFile( LPCTSTR, LPWIN32_FIND_DATA );
該函數(shù)在指定目錄尋找與指定文件名匹配的文件和文件夾,并返回一個(gè)查詢句柄。
BOOL FindNextFile( HANDLE,LPWIN32_FIND_DATA );
該函數(shù)繼續(xù)一個(gè)由查詢句柄指定的查詢過(guò)程。
BOOL FindClose( HANDLE );
該函數(shù)關(guān)閉指定的查詢句柄,結(jié)束指定的查詢。
DWORD GetFileAttributes( LPCTSTR );
該函數(shù)檢取指定的文件的屬性信息。
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -