关于文件的全部属性信息,总计有以下以下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。