---------------------------------------------------------------  
 
设计思路  
 
  在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编译通过。