引言:
對于大多數的IT企業和絕大多數的個人用戶而言,數據的備份主要是對數據內容的簡單備份,而很少涉及對備份數據自身屬性如文件屬性、所在文件夾的時間屬性等內容的備份。而在某些對數據管理有著非常嚴格要求的特殊行業中,對以上這些相關屬性信息的備份也是同等重要的。但是在目前的Windows操作系統下,不論是直接通過手工進行數據備份還是通過某些數據備份軟件來進行,都難以將這些信息完全保持原貌復制過來,尤其對于每時每刻均在發生變化的時間屬性更是難以保持其原始信息。不僅如此,在Windows操作系統下甚至沒有提供能直接修改此類屬性的工具和手段。為此,筆者對該問題做了研究,并總結出一套比較簡單的解決辦法。其中,對于文件屬性的備份與更改方法筆者已在電腦報天極網《在VC++下對文件屬性的獲取與更改》一文做了闡述,因此,本文在此就不再加以贅述,而著重對文件夾時間屬性的獲取與更改方法進行介紹。
設計思路
在Windows操作系統下并沒有提供任何可供修改文件夾時間屬性的方法和手段,即使是在Win32 API函數中,也只是提供了對文件時間屬性進行修改的函數調用,而沒有關于文件夾時間屬性修改的只言片語。雖然Windows所提供的備份程序能夠把待備份文件夾下的所有子文件夾的時間屬性按照原樣完整的復制過去,但是卻無法保持根目錄時間屬性的恒定。由此,可以考慮采取備份的方式來進行,并從同備份相關的Win32 API函數入手。具體而言,可以先以打開文件的方式來打開文件夾,然后就可以通過原本用于處理文件時間屬性的Win32 API函數GetFileTime()和SetFileTime()來獲取原始時間屬性并以其為參數來設置備份后的文件夾時間屬性了,這樣的處理可以確保文件夾在備份前后時間屬性的一致。
根據前面的分析可以看出,按照打開文件的方式來打開文件夾是整個處理過程的關鍵,通常主要用于創建、打開文件的Win32 API函數CreateFile()并非只能用來創建和打開文件對象,實際上它還可以用來創建、打開管道、郵槽、通訊資源、磁盤驅動器(只對Windows NT而言)、控制臺和文件夾(只能打開)等。下面給出CreateFile()的原型:
|
當用其進行文件夾打開操作時,第一個參數lpFileName應被設置成為待打開的文件夾的名稱;至于訪問模式可以根據需要靈活設置,對于本文而言,對源文件夾只進行讀取操作故可以設置為GENERIC_READ,對于備份后的文件夾由于需要將屬性信息寫入,因此需要有GENERIC_WRITE的支持;共享模式參數dwShareMode的設置與進行文件處理時的設置沒有什么區別,在此可以設置為FILE_SHARE_READ|FILE_SHARE_DELETE;由于CreateFile()函數在進行文件夾操作時,不能以創建方式進行,因此創建方式只能打開已經存在的對象,即dwCreationDisposition應當設置為OPEN_EXISTING;相比而言,dwFlagsAndAttributes參數的設置是比較重要的,正是通過將該參數設置為FILE_FLAG_BACKUP_SEMANTICS屬性才使CreateFile()函數來進行打開文件夾的操作。
通常,文件、文件夾的時間屬性指的是創建時間、最近訪問時間和最近修改時間等幾個具體屬性。對于文件的上述屬性可以通過GetFileTime()來獲取,對于文件夾,在通過CreateFile()函數將其打開后,其獲取得到的句柄可以當作文件句柄來使用。因此,通過GetFileTime()函數同樣也可以得到文件夾的時間屬性。GetFileTime()函數原型如下:
|
其中后三個參數均是指向FILETIME結構的指針,得到的也都是UTC時間,如果需要,可以通過FileTimeToLocalFileTime()函數將此UTC時間轉化成本地時間。而且還可以進一步通過FileTimeToSystemTime()函數將其從文件時間格式轉化成系統時間格式,轉化后的時間格式將保存在一個SYSTEMTIME結構對象中。類似的,在將時間信息寫入到文件夾屬性時,如果不是文件時間格式也應當通過SystemTimeToFileTime()函數將其從系統時間格式轉換成文件時間格式,然后再通過SetFileTime()函數將指定的時間寫入到文件夾的時間屬性中去。這樣,在進行數據備份和恢復的過程中,包括根目錄在內的所有文件夾都可以保持時間屬性的一致。
簡單示例
下面根據前面的講述而給出一個簡單的應用示例,通過此示例可以從指定的文件夾讀取時間屬性信息并可在經過修改后再回寫進去(在此僅對最近修改時間進行處理,對于其他的時間屬性可用類似的方法加以實現)。這里通過兩個函數GetDirTime()和SetDirTime()來實現對文件夾時間信息的獲取與更改處理,下面就以注釋的形式對這兩個函數的實現過程進行講解:
|
至此,可以很方便的通過調用GetDirTime()和SetDirTime()函數來實現對任意指定文件夾時間屬性的獲取與設置,具體為:
|
小結
本文通過CreateFile()函數打開文件夾,并在以后的處理中將其以文件來對待,從而可以使用GetFileTime()、SetFileTime()等函數來對其時間屬性進行獲取與寫入處理,可對包括根目錄在內的任意文件夾進行時間屬性設置。在數據的完整備份與復原等方面中有較好的應用前景。本文所述代碼在Windows 2000 Professional下,由Microsoft Visual C++ 6.0編譯通過。