在VC++下對檔案屬性的獲取與更改(轉)

heying1229發表於2007-07-28
一、 引言
  檔案是資料在磁碟上最常用的一種存放形式,也是在程式設計中與之經常打交道的一種程式設計物件,不少程式尤其是資料傳輸和處理類的應用程式更是需要頻繁的建立、讀取和寫入檔案。對於一些要求不是很嚴格的程式,我們往往只關心檔案的內容是否正確、檔案大小是否有增減或是再嚴格一些,看檔名是否符合規定等等。以上這些要素對於大多數程式而言顯然是可以滿足實際需求的,但對於某些特殊行業的一些有著比較嚴格要求的軟體系統,僅有以上要素還是遠遠不夠的,往往還需要對檔案的所有屬性諸如檔案的建立時間、檔案的最後訪問時間、檔案的最後修改時間等等進行提取處理與重新設定。

  二、 WIN32_FIND_DATA結構

  關於檔案的全部屬性資訊,總計有以下以下9種:檔案的標題名、檔案的屬性(只讀、存檔,隱藏等)、檔案的建立時間、檔案的最後訪問時間、檔案的最後修改時間、檔案大小的高位雙字、檔案大小的低位雙字、保留、保留。在這裡只有檔案標題名和檔案的長度可以透過CFile類比較方便的獲得,而對於其他幾種屬性的獲取和設定就無能為力了。

  在用findfirst()和findnext()函式去查詢磁碟檔案時經常使用的一個資料結構WIN32_FIND_DA他的成員變數裡包含了以上所有的檔案屬性,因此可以透過這個結構作為獲取和更改檔案屬性的手段。該結構的內容如下:

typedef struct _WIN32_FIND_DATA {
  DWORD dwFileAttributes; //檔案屬性
  FILETIME ftCreationTime; // 檔案建立時間
  FILETIME ftLastAccessTime; // 檔案最後一次訪問時間
  FILETIME ftLastWriteTime; // 檔案最後一次修改時間
  DWORD nFileSizeHigh; // 檔案長度高32位
  DWORD nFileSizeLow; // 檔案長度低32位
  DWORD dwReserved0; // 系統保留
  DWORD dwReserved1; // 系統保留
  TCHAR cFileName[ MAX_PATH ]; // 長檔名
  TCHAR cAlternateFileName[ 14 ]; // 8.3格式檔名
} WIN32_FIND_DATA, *PWIN32_FIND_DATA;

  可以透過FindFirstFile()函式根據當前的檔案存放路徑查詢該檔案來把待操作檔案的相關屬性讀取到WIN32_FIND_DATA結構中去:

WIN32_FIND_DATA ffd ;
HANDLE hFind = FindFirstFile("c: est.dat",&ffd);

  在使用這個結構時不能手工修改這個結構中的任何資料,結構對於開發人員來說只能作為一個只讀資料,其所有的成員變數都會由系統完成填寫。在MSDN幫助中可以查詢到關於WIN32_FIND_DATA結構的更加詳細的說明。

  三、 檔案屬性資訊的獲取與更改

  為了更好的儲存獲取到的檔案屬性資訊,對應於檔案屬性構造一個自定義的FILE_INFO資料結構,獲取的屬性資訊可暫存於此:

typedef struct _FILE_INFO {
  TCHAR szFileTitle[128]; //檔案的標題名
  DWORD dwFileAttributes; //檔案的屬性
  FILETIME ftCreationTime; //檔案的建立時間
  FILETIME ftLastAccessTime; //檔案的最後訪問時間
  FILETIME ftLastWriteTime; //檔案的最後修改時間
  DWORD nFileSizeHigh; //檔案大小的高位雙字
  DWORD nFileSizeLow; //檔案大小的低位雙字
  DWORD dwReserved0; //保留,為0
  DWORD dwReserved1; //保留,為0
} FILE_INFO, * PFILE_INFO;

  首先用FindFirstFile()函式將檔案屬性獲取到WIN32_FIND_DATA 結構物件FindFileData中去,之後可以用FindClose()將其關閉,並把FindFileData中的有關檔案屬性資訊的內容複製到自定義結構FILE_INFO的結構物件FileInfo中備用。下面是關於這部分描述的部分關鍵程式碼:

//宣告結構物件
FILE_INFO FileInfo;
WIN32_FIND_DATA FindFileData;
……
//獲取檔案屬性資訊
FindClose(FindFirstFile("Test.txt",&FindFileData));
memset(&FileInfo,0,sizeof(FILE_INFO));
……
//將檔案屬性資訊儲存到FileInfo中備用
strcpy(FileInfo.szFileTitle,myFile.GetFileTitle());
FileInfo.dwFileAttributes = FindFileData.dwFileAttributes;
FileInfo.ftCreationTime = FindFileData.ftCreationTime;
FileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime;
FileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime;
FileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh;
FileInfo.nFileSizeLow = FindFileData.nFileSizeLow;
……

  在獲取到檔案的原始屬性資訊後既可以原封不動的將屬性重新寫到檔案,也可以對其中某一項或某幾項屬性內容進行修改後再行寫入檔案,從而達到更改檔案屬性的目的。比如可以用SetFileTime()函式設定檔案的建立時間、最近一次訪問時間以及最近一次修改的時間等等:

SetFileTime((HANDLE)destFile.m_hFile, //待寫入的檔案控制程式碼
&FileInfo.ftCreationTime, //檔案的建立時間
&FileInfo.ftLastAccessTime, //檔案最近一次的訪問時間
&FileInfo.ftLastWriteTime); //檔案最近一次的修改時間

  也可以用SetFileAttributes() 函式實現對檔案屬性的修改:

SetFileAttributes(FileInfo.szFileTitle,FileInfo.dwFileAttributes);

  至於檔名的修改則更加簡單,直接在建立檔案時在CreateFile()或CFile類的成員函式Open裡直接對檔名引數進行設定即可。

  小結:本文透過對WIN32_FIND_DATA結構和SetFileTime()、SetFileAttributes()等主要函式實現了對磁碟檔案的相關屬性資訊的獲取與修改。用此技術可以在通訊等對檔案有嚴格要求的應用領域實現檔案全部資訊(包括檔案內容、檔名以及檔案屬性等)的完整傳送。本文所述程式在Windows 98下由Microsoft Visual C++ 6.0編譯除錯透過。
[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10172717/viewspace-928882/,如需轉載,請註明出處,否則將追究法律責任。

相關文章