程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> VC編程改變指定的文件或文件夾的屬性

VC編程改變指定的文件或文件夾的屬性

編輯:vc教程

  文件是數據在磁盤上最常用的一種存放形式,也是在程序設計中與之經常打交道的一種編程對象,不少程序尤其是數據傳輸和處理類的應用程序更是需要頻繁的創建、讀取和寫入文件。對於一些要求不是很嚴格的程序,我們往往只關心文件的內容是否正確、文件大小是否有增減或是再嚴格一些,看文件名是否符合規定等等。以上這些要素對於大多數程序而言顯然是可以滿足實際需求的,但對於某些特殊行業的一些有著比較嚴格要求的軟件系統,僅有以上要素還是遠遠不夠的,往往還需要對文件的所有屬性諸如文件的創建時間、文件的最後訪問時間、文件的最後修改時間、文件的讀寫、文件的隱現等等進行提取處理與重新設置。例如,修改文件的讀寫隱現等屬性,可以實現文件的保護和控制,尤其是修改文件的產生修改和訪問時間,可以避免因防病毒更改系統時間而造成的文件修改時間的紊亂所形成的不便。在DOS下文件的屬性可以用DOS命令加以修改,在Windows下,可以通過右鍵的屬性改變一組文件和文件夾的讀寫屬性,但是卻不能修改文件的產生修改和訪問時間,並且不能修改子目錄下的文件和文件夾的屬性。

  本實例基於Windows的API,設計了通用的文件和文件夾的屬性(包括文件的產生修改和訪問時間以及讀寫隱現等)的修改方法,並實現了其Visual C++程序編碼。程序運行後,點擊"修改屬性"按鈕,就可以將項目文件夾中的"2.doc"文檔的屬性修改的與"1.doc"文檔一致。

 
  一、實現方法

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

  Windows中的API函數組提供了用於文件讀寫、屬性設置的眾多API函數,例如:

HANDLE CreateFile( LPCTSTR, DWORD, DWORD,LPSECURITY_ATTRIBUTES, DWORD,DWord,HANDLE ); 

  該函數產生或者打開一個系統對象,並返回一個用以訪問該對象的句柄,這些對象可以是文件、文件夾、管道等。

HANDLE FindFirstFile( LPCTSTR, LPWIN32_FIND_DATA );

  該函數在指定目錄尋找與指定文件名匹配的文件和文件夾,並返回一個查詢句柄。

BOOL FindNextFile( HANDLE,LPWIN32_FIND_DATA );

  該函數繼續一個由查詢句柄指定的查詢過程。

BOOL FindClose( HANDLE );

  該函數關閉指定的查詢句柄,結束指定的查詢。

DWord GetFileAttributes( LPCTSTR );

  該函數檢取指定的文件的屬性信息。 

BOOL SetFileAttributes( LPCTSTR,DWord );

  該函數設置指定的文件的屬性信息。

  Windows中的API函數組提供了有關時間轉換的眾多API函數,例如:

BOOL SystemTimeToFileTime( CONST SYSTEMTIME *,LPFILETIME );

  該函數將系統時間轉換成文件時間,文件時間是一個64位長度的數,表示從1601年1月1日起的時間偏移,以千萬分之一秒為單位。  

BOOL LocalFileTimeToFileTime(CONST FILETIME *,LPFILETIME );  

  該函數將本時區的文件時間轉換成格林威治時間的文件時間。 

BOOL SetFileTime( HANDLE,CONST FILETIME*,CONST FILETIME *,CONST FILETIME * );

  該函數設置文件產生修改和訪問的時間。 至於文件名的修改則更加簡單,直接在創建文件時在CreateFile()或CFile類的成員函數Open裡直接對文件名參數進行設置即可。 

  在上面的函數中,FindFirstFile()和FindNextFile()使用的一個數據結構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: 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);


  二、編程步驟

  1、啟動Visual C++6.0,生成一個基於對話框的應用程序,命名為"File";

  2、修改對話框界面,在其上放置一個按鈕控件,Caption設置為"修改屬性",然後使用Class Wizard為該按鈕添加鼠標單擊消息響應函數;

  3、在項目文件夾中放置"1.doc"、"2.doc"文件;

  4、添加代碼,編譯運行程序。

  三、程序代碼

/////////////////////////////////////
void CFileDlg::OnTest()
{
myFile.Open("1.doc", CFile::modeReadWrite);
destFile.Open("2.doc", CFile::modeReadWrite);
//聲明結構對象
FILE_INFO FileInfo;
WIN32_FIND_DATA FindFileData;
//獲取文件屬性信息
FindClose(FindFirstFile("1.doc", &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((HANDLE)destFile.m_hFile, //待寫入的文件句柄
&FileInfo.ftCreationTime, //文件的創建時間
&FileInfo.ftLastAccessTime, //文件最近一次的訪問時間
&FileInfo.ftLastWriteTime); //文件最近一次的修改時間
SetFileAttributes(FileInfo.szFileTitle,FileInfo.dwFileAttributes);
myFile.Close();
destFile.Close();
}

  四、小結

  本文通過對WIN32_FIND_DATA結構和SetFileTime()、SetFileAttributes()等主要函數實現了對磁盤文件的相關屬性信息的獲取與修改。用此技術可以在通訊等對文件有嚴格要求的應用領域實現文件或文件夾的全部信息(包括文件內容、文件名以及文件屬性等)的完整傳送。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved