📄 文件夹时间属性的获取与更改.txt
字号:
VC++实现文件夹时间属性的获取与更改
引言:
对于大多数的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编译通过。
信息标题:VC编程改变指定的文件或文件夹的属性
发布人:网络无名
发布日期:2007-4-4
浏览次数:64
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 );
该函数检取指定的文件的属性信息。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -