文件管理
#pragma once #include <Strsafe.h> #include <list> using std::list; typedef struct _FILE_INFO { WCHAR szFilePath[MAX_PATH]; // 文件路径 BOOL bIsFolder; // 是否为文件夹 DWORD64 qwFileSize; // 文件大小 DWORD dwAttribute; // 文件属性 WCHAR szAttributeDescription[16]; // 文件属性描述 SYSTEMTIME stcCreatTime; // 创建时间 SYSTEMTIME stcLastAccessTime; // 最后访问时间 SYSTEMTIME stcLastWriteTime; // 最后写入时间 }FILE_INFO,*PFILE_INFO; class CFileControl { public: CFileControl(void); CFileControl(LPCTSTR lpFileName); ~CFileControl(void); public: DWORD GetMyProcessDir(LPWSTR &lpDirPath); // 获取本进程当前目录 BOOL SetMyProcessDir(LPWSTR lpNewDir); // 设置程序的当前目录 DWORD GetMyProcessImagePath(LPWSTR &lpPath); // 获取本进程映像路径 DWORD GetProcessImagePath(LPWSTR lpName,LPWSTR &lpPath); // 根据进程名获取映像路径 BOOL SetFileIsOnlyRead(LPWSTR lpPath); // 设置文件为只读 BOOL SetFileIsHidden(LPWSTR lpPath); // 设置文件为隐藏 BOOL GetFileAttribute(LPWSTR lpPath, FILE_INFO &stcFileInfo); // 将文件属性压入队列 BOOL GetFileList(LPWSTR lpName, list<FILE_INFO> &lstFileInfo); // 获取当前目录下文件列表 DWORD GetFileTree(LPWSTR lpName, DWORD dwLeve=1); // 获取文件树 private: HANDLE m_hFile; list<FILE_INFO> m_lstFileInfo; };
#include "stdafx.h" #include "FileControl.h" CFileControl::CFileControl(void){} CFileControl::CFileControl(LPCTSTR lpFileName) { m_hFile = CreateFile( lpFileName, // 文件名 GENERIC_ALL, // 存取方式 FILE_SHARE_WRITE|FILE_SHARE_READ, // 共享方式 NULL, // 文件句柄继承属性 CREATE_ALWAYS, // 操作模式 FILE_ATTRIBUTE_ARCHIVE, // 文件属性/标志 NULL); // 模板文件句柄,一般为NULL } CFileControl::~CFileControl(void){} DWORD CFileControl::GetMyProcessDir(LPWSTR &lpDirPath) { return GetCurrentDirectory(MAX_PATH,lpDirPath); } BOOL CFileControl::SetMyProcessDir(LPWSTR lpNewDir) { return SetCurrentDirectory(lpNewDir); } DWORD CFileControl::GetMyProcessImagePath(LPWSTR &lpDirPath) { return GetModuleFileName(NULL,lpDirPath,MAX_PATH); } DWORD CFileControl::GetProcessImagePath(LPWSTR lpName,LPWSTR &lpPath) { return GetModuleFileName(GetModuleHandle(lpName), lpPath, MAX_PATH); } BOOL CFileControl::SetFileIsOnlyRead(LPWSTR lpPath) { // 1. 获取原来的文件属性 DWORD dwFileAttributes = GetFileAttributes(lpPath); // 2. 将只读属性附加到原来的文件属性上 dwFileAttributes |= FILE_ATTRIBUTE_READONLY; // 3. 设置文件属性 return SetFileAttributes(lpPath, dwFileAttributes); } BOOL CFileControl::SetFileIsHidden(LPWSTR lpPath) { // 1. 获取原来的文件属性 DWORD dwFileAttributes = GetFileAttributes(lpPath); // 2. 将隐藏属性附加到原来的文件属性上 dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN; // 3. 设置文件属性 return SetFileAttributes(lpPath, dwFileAttributes); } BOOL CFileControl::GetFileAttribute(LPWSTR lpPath, FILE_INFO &stcFileInfo) { // 1. 文件路径 wcscpy_s(stcFileInfo.szFilePath, lpPath); // 2. 获取时间信息 WIN32_FILE_ATTRIBUTE_DATA wfad; GetFileAttributesEx( lpPath, GetFileExInfoStandard, &wfad); // 2.1 获取创建时间 FILETIME ftLocal; FileTimeToLocalFileTime( &wfad.ftCreationTime, &ftLocal ); // 调整为系统所在时区的时间 FileTimeToSystemTime( &ftLocal, &stcFileInfo.stcCreatTime ); // 转换为SYSTEMTIME格式 // 2.2 获取最后访问时间 FileTimeToLocalFileTime( &wfad.ftLastAccessTime, &ftLocal ); // 调整为系统所在时区的时间 FileTimeToSystemTime( &ftLocal, &stcFileInfo.stcLastAccessTime ); // 转换为SYSTEMTIME格式 // 2.3 获取最后修改时间 FileTimeToLocalFileTime( &wfad.ftLastWriteTime, &ftLocal ); // 调整为系统所在时区的时间 FileTimeToSystemTime( &ftLocal, &stcFileInfo.stcLastWriteTime ); // 转换为SYSTEMTIME格式 // 3. 获取文件大小 stcFileInfo.qwFileSize = wfad.nFileSizeHigh; stcFileInfo.qwFileSize <<= sizeof(DWORD)*8; stcFileInfo.qwFileSize += wfad.nFileSizeLow; // 4. 文件属性 stcFileInfo.dwAttribute = wfad.dwFileAttributes; if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_ARCHIVE) wcscpy_s(stcFileInfo.szAttributeDescription, L"<ARCHIVE> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_COMPRESSED) wcscpy_s(stcFileInfo.szAttributeDescription, L"<压缩> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_DIRECTORY) wcscpy_s(stcFileInfo.szAttributeDescription, L"<目录> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_ENCRYPTED) wcscpy_s(stcFileInfo.szAttributeDescription, L"<加密> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_HIDDEN) wcscpy_s(stcFileInfo.szAttributeDescription, L"<隐藏> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_NORMAL) wcscpy_s(stcFileInfo.szAttributeDescription, L"<NORMAL> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_OFFLINE) wcscpy_s(stcFileInfo.szAttributeDescription, L"<OFFLINE> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_READONLY) wcscpy_s(stcFileInfo.szAttributeDescription, L"<只读> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_SPARSE_FILE) wcscpy_s(stcFileInfo.szAttributeDescription, L"<SPARSE> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_SYSTEM) wcscpy_s(stcFileInfo.szAttributeDescription, L"<系统文件> "); if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_TEMPORARY) wcscpy_s(stcFileInfo.szAttributeDescription, L"<临时文件> "); return TRUE; } BOOL CFileControl::GetFileList(LPWSTR lpName, list<FILE_INFO> &lstFileInfo) { // 1. 构造代表子目录和文件夹路径的字符串,使用通配符“*” WCHAR szFilePath[MAX_PATH]; StringCbCopy(szFilePath, MAX_PATH, lpName); StringCbCat(szFilePath, MAX_PATH, L"\\*"); // 2. 获取第一个文件/目录,并获得查找句柄 WIN32_FIND_DATA FindFileData; HANDLE hListFile = FindFirstFile(szFilePath,&FindFileData); int n = GetLastError(); if ( INVALID_HANDLE_VALUE == hListFile ) return FALSE; // 3. 开始循环遍历获取文件名 do { FILE_INFO stcInfo = {0}; // 3.1 判断是否是本级目录或上级目录的名称,是的话则结束本次循环 if ( !lstrcmp(FindFileData.cFileName, L".") || !lstrcmp(FindFileData.cFileName, L"..") ) { continue; } // 3.2 将获取到的文件名保存在结构体中 wcscpy_s(stcInfo.szFilePath, FindFileData.cFileName); // 3.3 获取完整路径名 WCHAR szFullPath[MAX_PATH]; StringCbPrintf(szFullPath, MAX_PATH, L"%s\\%s", lpName, FindFileData.cFileName); // 3.4 如果不是目录,则获取详细信息 if(FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) stcInfo.bIsFolder = TRUE; else GetFileAttribute(szFullPath,stcInfo); // 3.5 将获取到的文件信息压入到链表中 lstFileInfo.push_back(stcInfo); } while ( FindNextFile(hListFile, &FindFileData) ); return TRUE; } DWORD CFileControl::GetFileTree(LPWSTR lpName, DWORD dwLeve) { // 1. 如果层级是为0则返回,否则将层级-1后继续 if ( !dwLeve-- ) return 0; // 2. 构造代表子目录和文件夹路径的字符串,使用通配符“*” WCHAR szFilePath[MAX_PATH]; StringCbCopy(szFilePath, MAX_PATH, lpName); StringCbCat(szFilePath, MAX_PATH, L"\\*"); // 3. 获取第一个文件/目录,并获得查找句柄 WIN32_FIND_DATA FindFileData; HANDLE hListFile = FindFirstFile(szFilePath,&FindFileData); if ( INVALID_HANDLE_VALUE == hListFile ) return 0; // 4. 开始循环遍历获取文件名 DWORD dwFileCount = 0; do { // 4.1 判断是否是本级目录或上级目录的名称,是的话则结束本次循环 if ( !lstrcmp(FindFileData.cFileName, L".") || !lstrcmp(FindFileData.cFileName, L"..") ) { continue; } // 4.2 获取完整路径名 WCHAR szFullPath[MAX_PATH]; StringCbPrintf(szFullPath, MAX_PATH, L"%s\\%s", lpName, FindFileData.cFileName); // 4.3 如果是目录,则递归调用,列举下级目录 if(FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) dwFileCount += GetFileTree(szFullPath,dwLeve); // 4.4 将文件数量+1 dwFileCount++; } while ( FindNextFile(hListFile, &FindFileData) ); // 5. 返回本次遍历到的文件总数 return dwFileCount; }
让数据变得更安全!