VC++實現對檔案夾時間的修改

來源:互聯網
上載者:User

VC++實現對檔案夾時間的修改

摘要: 本文給出了一種通過VC++程式對檔案夾的時間屬性資訊進行擷取與更改的一種方法。

  關鍵詞: 檔案夾;時間屬性;Visual C++ 6.0

  引言:

   通常在資料維護與資料管理等工作中,經常要對各類資料進行備份操作。對於大多數的IT企業和絕大多數的個人使用者而言,資料的備份主要是對資料內容的簡單 備份,而很少涉及對備份資料自身屬性如檔案屬性、所在檔案夾的時間屬性等內容的備份。而在某些對資料管理有著非常嚴格要求的特殊行業中,對以上這些相關屬 性資訊的備份也是同等重要的。但是在目前的Windows作業系統下,不論是直接通過手工進行資料備份還是通過某些資料備份軟體來進行,都難以將這些資訊 完全保持原貌複製過來,尤其對於每時每刻均在發生變化的時間屬性更是難以保持其原始資訊。不僅如此,在Windows作業系統下甚至沒有提供能直接修改此 類屬性的工具和手段。為此,筆者對該問題做了研究,並總結出一套比較簡單的解決辦法。其中,對於檔案屬性的備份與更改方法筆者已在天極網《在VC++下對檔案屬性的擷取與更改》一文做了闡述,因此,本文在此就不再加以贅述,而著重對檔案夾時間屬性的擷取與更改方法進行介紹。

  設計思路

  在Windows作業系統下並沒有提供任何可供修改檔案夾時間屬性的方法和手段,即使是在Win32 API函數中,也只是提供了對檔案時間屬性進行修改的函數調用,而沒有關於檔案夾時間屬性修改的隻言片語。雖然Windows所提供的備份程式能夠把待備份檔案夾下的所有子檔案夾的時間屬性按照原樣完整的複製過去,但是卻無法保持根目錄時間屬性的恒定。由此,可以考慮採取備份的方式來進行,並從同備份相關的Win32 API函數入手。具體而言,可以先以開啟檔案的方式來開啟檔案夾,然後就可以通過原本用於處理檔案時間屬性的Win32 API函數GetFileTime()和SetFileTime()來擷取原始時間屬性並以其為參數來設定備份後的檔案夾時間屬性了,這樣的處理可以確保檔案夾在備份前後時間屬性的一致。

   根據前面的分析可以看出,按照開啟檔案的方式來開啟檔案夾是整個處理過程的關鍵,通常主要用於建立、開啟檔案的Win32 API函數CreateFile()並非只能用來建立和開啟檔案對象,實際上它還可以用來建立、開啟管道、郵槽、通訊資源、磁碟機(只對 Windows NT而言)、控制台和檔案夾(只能開啟)等。下面給出CreateFile()的原型:

HANDLE CreateFile(
 LPCTSTR lpFileName, // 檔案名稱指標
 DWORD dwDesiredAccess, // 訪問模式
 DWORD dwShareMode, // 共用模式
 LPSECURITY_ATTRIBUTES lpSecurityAttributes, //安全屬性
 DWORD dwCreationDisposition, // 建立方式
 DWORD dwFlagsAndAttributes, // 檔案屬性
 HANDLE hTemplateFile // 指向待覆制屬性的檔案指標
);

   當用其進行檔案夾開啟操作時,第一個參數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()函數原型如下:

BOOL GetFileTime(
 HANDLE hFile, // 檔案控制代碼
 LPFILETIME lpCreationTime, // 建立時間的地址
 LPFILETIME lpLastAccessTime, // 最近訪問時間的地址
 LPFILETIME lpLastWriteTime // 最近修改時間的地址
);

   其中後三個參數均是指向FILETIME結構的指標,得到的也都是UTC時間,如果需要,可以通過FileTimeToLocalFileTime() 函數將此UTC時間轉化成本地時間。而且還可以進一步通過FileTimeToSystemTime()函數將其從檔案時間格式轉化成系統時間格式,轉化 後的時間格式將儲存在一個SYSTEMTIME結構對象中。類似的,在將時間資訊寫入到檔案夾屬性時, 如果不是檔案時間格式也應當通過SystemTimeToFileTime()函數將其從系統時間格式轉換成檔案時間格式,然後再通過 SetFileTime()函數將指定的時間寫入到檔案夾的時間屬性中去。這樣,在進行資料備份和恢複的過程中,包括根目錄在內的所有檔案夾都可以保持時 間屬性的一致。

下面根據前面的講述而給出一個簡單的應用樣本,通過此樣本可以從指定的檔案夾讀取時間屬性資訊並可在經過修改後再回寫進去(在此僅對最近修改時間進行處 理,對於其他的時間屬性可用類似的方法加以實現)。這裡通過兩個函數GetDirTime()和SetDirTime()來實現對檔案夾時間資訊的擷取與 更改處理,下面就以注釋的形式對這兩個函數的實現過程進行講解:

// 擷取指定檔案夾的時間屬性,入口參數DirName指定了待處理的檔案夾,stime為一
// 指向SYSTEMTIME結構的指標
BOOL CSetForderTimeDlg::GetDirTime(CString DirName, SYSTEMTIME &stime){
 // 開啟檔案夾
 HANDLE hDir = CreateFile (DirName, GENERIC_READ,
   FILE_SHARE_READ|FILE_SHARE_DELETE,
   NULL, OPEN_EXISTING,
   FILE_FLAG_BACKUP_SEMANTICS, NULL);
 FILETIME lpCreationTime; // 檔案夾的建立時間
 FILETIME lpLastAccessTime; // 對檔案夾的最近訪問時間
 FILETIME lpLastWriteTime; // 檔案夾的最近修改時間
 // 擷取檔案夾時間屬性資訊
 if (GetFileTime(hDir, &lpCreationTime, &lpLastAccessTime, &lpLastWriteTime)){
  FILETIME ftime;
  FileTimeToLocalFileTime(&lpLastWriteTime, &ftime); // 轉換成本地時間
  FileTimeToSystemTime(&ftime, &stime); // 轉換成系統時間格式
 }
 CloseHandle(hDir); // 關閉開啟過的檔案夾
 return retval;
}

// 設定指定檔案夾的時間屬性,入口參數DirName指定了待處理的檔案夾,new_time
// 為一指向SYSTEMTIME結構的指標
BOOL CSetForderTimeDlg::SetDirTime(CString DirName, SYSTEMTIME new_stime){
 // 開啟目錄的Win32 API調用
 HANDLE hDir = CreateFile(DirName, GENERIC_READ|GENERIC_WRITE,
   FILE_SHARE_READ|FILE_SHARE_DELETE,
   NULL, OPEN_EXISTING,
   FILE_FLAG_BACKUP_SEMANTICS, NULL);
 FILETIME lpCreationTime; // 檔案夾的建立時間
 FILETIME lpLastAccessTime; // 對檔案夾的最近訪問時間
 FILETIME lpLastWriteTime; // 對檔案夾的最近修改時間
 SystemTimeToFileTime(&new_stime, &lpCreationTime); // 轉換成檔案時間格式
 SystemTimeToFileTime(&new_stime, &lpLastAccessTime);
 SystemTimeToFileTime(&new_stime, &lpLastWriteTime);
 // 設定檔案夾的時間屬性
 BOOL retval = SetFileTime(hDir, &lpCreationTime, &lpLastAccessTime,           &lpLastWriteTime);
 CloseHandle(hDir); // 關閉檔案夾
 return retval;
}

  至此,可以很方便的通過調用GetDirTime()和SetDirTime()函數來實現對任意指定檔案夾時間屬性的擷取與設定,具體為:

SYSTEMTIME stime; // 系統時間結構對象
if (GetDirTime(m_Path, stime))
{
 // 如果擷取檔案夾時間屬性成功,擷取到的時間資訊將儲存在stime結構對象中
 ……
 // 如果需要可以對擷取到的時間屬性進行修改,也可以保留不變
 ……
 // 將修改後的時間屬性回寫到檔案夾
 SetDirTime(m_Path, stime);
}

  小結

   本文通過CreateFile()函數開啟檔案夾,並在以後的處理中將其以檔案來對待,從而可以使用GetFileTime()、 SetFileTime()等函數來對其時間屬性進行擷取與寫入處理,可對包括根目錄在內的任意檔案夾進行時間屬性設定。在資料的完整備份與複原等方面中 有較好的應用前景。本文所述代碼在Windows 2000 Professional下,由Microsoft Visual C++ 6.0編譯通過。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.