檔案屬性結構體:WIN32_FIND_DATA
阿新 • • 發佈:2019-02-10
關於檔案的全部屬性資訊,總計有以下以下9種:檔案的標題名、檔案的屬性(只讀、存檔,隱藏等)、檔案的建立時間、檔案的最後訪問時間、檔案的最後修改時間、檔案大小的高位雙字、檔案大小的低位雙字、保留、保留。在這裡只有檔案標題名和檔案的長度可以通過CFile類比較方便的獲得,而對於其他幾種屬性的獲取和設定就無能為力了。
在用findfirst()和findnext()函式去查詢磁碟檔案時經常使用的一個數據結構WIN32_FIND_DATA的成員變數裡包含了以上所有的檔案屬性,因此可以通過這個結構作為獲取和更改檔案屬性的手段。該結構的內容如下:
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:\\test.dat",&ffd);
查詢C盤的temp資料夾下所有txt的檔案
HANDLE hf = FindFirstFile("c:\\temp\\*.txt", &wfd);
在使用這個結構時不能手工修改這個結構中的任何資料,結構對於開發人員來說只能作為一個只讀資料,其所有的成員變數都會由系統完成填寫。在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裡直接對檔名引數進行設定即可。
我可以定義一個類:
class CFindFile
#008 {
#009 public:
#010
#011 CFindFile(void)
#012 {
#013 m_hFind = INVALID_HANDLE_VALUE;
#014 m_bFound = false;
#015 memset(&m_FindFileData,0,sizeof(m_FindFileData));
#016 }
#017
#018 ~CFindFile(void)
#019 {
#020 if (m_hFind != INVALID_HANDLE_VALUE)
#021 {
#022 ::FindClose(m_hFind);
#023 }
#024 }
#025
#026 //找到第一個檔案。
#027 void First(LPCTSTR lpFileName)
#028 {
#029 m_hFind = ::FindFirstFile(lpFileName,&m_FindFileData);
#030 if (m_hFind != INVALID_HANDLE_VALUE)
#031 {
#032 m_bFound = true;
#033 }
#034 else
#035 {
#036 m_bFound = false;
#037 }
#038 }
#039
#040 //查詢一下檔案。
#041 void Next(void)
#042 {
#043 m_bFound = FindNextFile(m_hFind, &m_FindFileData) ? true:false;
#044 }
#045
#046 //是否可以查詢一下檔案。
#047 bool IsOK(void) const
#048 {
#049 return m_bFound;
#050 }
#051
#052 //返回當前檔案的屬性。
#053 const WIN32_FIND_DATA& GetCurFile(void)
#054 {
#055 return m_FindFileData;
#056 }
#058 protected:
#059 HANDLE m_hFind; //儲存當查詢的位置控制代碼。
#060 bool m_bFound; //當前查詢是否成功。
#061 WIN32_FIND_DATA m_FindFileData;//儲存當前檔案的屬性。
#063 };
另外:FILETIME可以通過FileTimeToSystemTime()把它轉換為系統時間:
typedef struct _SYSTEMTIME {
WORD [url=]wYear[/url];
WORD [url=]wMonth[/url];
WORD [url=]wDayOfWeek[/url];
WORD [url=]wDay[/url];
WORD [url=]wHour[/url];
WORD [url=]wMinute[/url];
WORD [url=]wSecond[/url];
WORD [url=]wMilliseconds[/url];
} SYSTEMTIME。
在用findfirst()和findnext()函式去查詢磁碟檔案時經常使用的一個數據結構WIN32_FIND_DATA的成員變數裡包含了以上所有的檔案屬性,因此可以通過這個結構作為獲取和更改檔案屬性的手段。該結構的內容如下:
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:\\test.dat",&ffd);
查詢C盤的temp資料夾下所有txt的檔案
HANDLE hf = FindFirstFile("c:\\temp\\*.txt", &wfd);
在使用這個結構時不能手工修改這個結構中的任何資料,結構對於開發人員來說只能作為一個只讀資料,其所有的成員變數都會由系統完成填寫。在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裡直接對檔名引數進行設定即可。
我可以定義一個類:
class CFindFile
#008 {
#009 public:
#010
#011 CFindFile(void)
#012 {
#013 m_hFind = INVALID_HANDLE_VALUE;
#014 m_bFound = false;
#015 memset(&m_FindFileData,0,sizeof(m_FindFileData));
#016 }
#017
#018 ~CFindFile(void)
#019 {
#020 if (m_hFind != INVALID_HANDLE_VALUE)
#021 {
#022 ::FindClose(m_hFind);
#023 }
#024 }
#025
#026 //找到第一個檔案。
#027 void First(LPCTSTR lpFileName)
#028 {
#029 m_hFind = ::FindFirstFile(lpFileName,&m_FindFileData);
#030 if (m_hFind != INVALID_HANDLE_VALUE)
#031 {
#032 m_bFound = true;
#033 }
#034 else
#035 {
#036 m_bFound = false;
#037 }
#038 }
#039
#040 //查詢一下檔案。
#041 void Next(void)
#042 {
#043 m_bFound = FindNextFile(m_hFind, &m_FindFileData) ? true:false;
#044 }
#045
#046 //是否可以查詢一下檔案。
#047 bool IsOK(void) const
#048 {
#049 return m_bFound;
#050 }
#051
#052 //返回當前檔案的屬性。
#053 const WIN32_FIND_DATA& GetCurFile(void)
#054 {
#055 return m_FindFileData;
#056 }
#058 protected:
#059 HANDLE m_hFind; //儲存當查詢的位置控制代碼。
#060 bool m_bFound; //當前查詢是否成功。
#061 WIN32_FIND_DATA m_FindFileData;//儲存當前檔案的屬性。
#063 };
另外:FILETIME可以通過FileTimeToSystemTime()把它轉換為系統時間:
typedef struct _SYSTEMTIME {
WORD [url=]wYear[/url];
WORD [url=]wMonth[/url];
WORD [url=]wDayOfWeek[/url];
WORD [url=]wDay[/url];
WORD [url=]wHour[/url];
WORD [url=]wMinute[/url];
WORD [url=]wSecond[/url];
WORD [url=]wMilliseconds[/url];
} SYSTEMTIME。