判断的方式太多太多,这里暂时列举5中方式。
在文章开始之前,由于需要用到CString转char功能,所以先介绍一个CString转char的方法:
想知道更多参见CString与char *互转总结
由于本文使用的Unicode编码模式,所以如下:
int CIsFileExistDlg::UnicodeToChar(CString& strIn, char* pOut, int nLen)
{
if (NULL == pOut)
{
return 0;
}
int len = WideCharToMultiByte(CP_ACP, 0, strIn, -1, NULL, 0, NULL, NULL);
len = min(len, nLen);
WideCharToMultiByte(CP_ACP, 0, strIn, -1, pOut, len, NULL, NULL);
if (len <nLen)
{
pOut[len] = 0;
}
return len;
}
一、CFileFind
1、头文件
afx.h
2、功能
执行本地文件的查找(查找某个具体的文件,查找某类文件x*.x*,查找所有文件*.*
3、延伸
- CFileFind类是CGopherFileFind和CFtpFileFind类的基类。
- CFileFind类的构造函数::CFileFind()和关闭函数::Close(),需要成对使用。
4、CFileFind类的成员函数我根据其操作特性划分为3类:
+ 查找操作类
+ 获得文件属性类
+ 判断文件属性类。
查找操作类
::FindFile();
::FindNextFile();
获得文件属性类
::GetCreationTime();
::GetLastAccessTime();
::GetLastWriteTime();
::GetFileName(); //带后缀的文件名
::GetRoot(); //盘符
::GetFilePath(); //全路径
::GetFileTitle(); //不带后缀的文件名
::GetFileURL(); //URL串
::GetLength(); //
判断文件属性类
::IsArchived();
::IsCompressed();
::IsDirectory();
::IsDots();
::IsHidden();
::IsNormal();
::IsReadOnly();
::IsSystem();
::IsTemporary();
::MatchesMask();
5、CFileFind类中成员函数使用应注意的顺序
在创建了CFileFind对象后,先执行::FindFile()函数,然后执行::FindNextFile(),然后选择执行(获得文件属性类)的函数或者(判断文件属性类)函数。
6、CFileFind类成员函数的详细分析
virtual BOOL FindFile(LPCTSTR pstrName = null,DWORD dwUnused = 0);
//该函数若返回非0 则表明执行成功,0 则表明执行不成功。
//pstrName:需要查找的文件名,例:“E:\\编程工具\\VC++\\MFC例子.rar”,“E:\\编程工具\\VC++\\MFC*.rar”,“E:\\编程工具\\VC++\\*.*”,也可以是NULL表示“*.*”。
//dwUnused:必须为0
virtual BOOL FindNextFile();
//该函数返回值非0 还有符合条件的文件, 0表示是最后一个文件。
virtual BOOL GetCreationTime(FILETIME *pFileTime) const;
virtual BOOL GetCreationTime(CTime& refTime) const;
//该函数用来获得查找到的某个文件的创建时间,返回值非0 获得创建时间成功操作,0表示执行获得创建时间失败或者FindNextFile()没有被执行的时候。
//FILETIME *:容纳时间的结构指针
//CTime&:容纳时间的对象地址
此处介绍:FILETIME和CTime相互转换的处理方法:
#FILETIME转CTime的方法:
A、CTime对象在初始化时可以传递FILETIME结构
FILETIME ft;
CTime time(ft);
B、将FILETIME转换为SYSTEMTIME,然后CTime对象在初始化时可以传递SYSTEMTIME结构
FILETIME ft;
SYSTEMTIME st;
BOOL bSuccess = ::FileTimeToSystemTime(&ft , &st);
CTime time(st);
#CTime转FILETIME方法:
CTime time(CTime::GetCurrentTime());
SYSTEMTIME st;
time.GetAsSystemTime(st);
FILETIME ft;
::SystemTimeToFileTime(&st,&ft);
virtual BOOL GetLastAccessTime(FILETIME *pFileTime) const;
virtual BOOL GetLastAccessTime(CTime& refTime) const;
//该函数用来获得某个文件最后被访问的时间,非0表示执行成功,0表示执行失败或者FindNextFile()函数没有执行的时候。
virtual BOOL GetLastWriteTime(FILETIME *pFileTime) const;
virtual BOOL GetLastWriteTime(CTime& refTime) const;
//该函数用来获得某个文件最后被访问的时间,非0表示执行成功,0表示执行失败或者FindNextFile()函数没有执行的时候。
virtual CString GetFilePath() const;
//该函数用来获得查找到的文件绝对路径,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“E:\\编程工具\\VC++\\MFC.rar”
virtual CString GetFileName() const;
//该函数用来获得查找到的文件的全称,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“MFC.rar”
virtual CString GetFileTitle() const;
//该函数用来获得查找到的文件的名称,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“MFC”
virtual CString GetRoot() const;
//该函数用来获得查找到的文件的根目录,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“E:\\编程工具\\VC++\\”
virtual CString GetFileURL() const;
//该函数用来获得查找到的文件的URL路径,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“file://E:\\编程工具\\VC++\\MFC.rar”
DWORD GetLength() const;
//该函数返回值获得查找到的文件的长度,必须在执行了FindNextFile()后该函数才能执行成功。
BOOL IsArchived() const;
//该函数用来判断查找的文件属性是否是档案文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsCompressed() const;
//该函数用来判断查找的文件属性是否是压缩文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsDirectory() const;
//该函数用来判断查找的文件属性是否是路径文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsDots() const;
//该函数用来判断查找的文件属性是否是“.”,“..”,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsHidden() const;
//该函数用来判断查找的文件属性是否隐藏文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功
BOOL IsNormal() const;
//该函数用来判断查找的
7、例子
CFileFind fFile;
BOOL bRet = fFile.FindFile(strPath);
if (bRet)
{
std::cout << "CFileFind:" << "文件或者文件夹查找成功" << std::endl;
std::cout << std::endl;
while (bRet)
{
bRet = fFile.FindNextFile();
if (fFile.IsDots())
{
continue;
}
if (fFile.IsDirectory())
{
std::cout << "CFileFind:" << "文件夹查找成功" << std::endl;
std::cout << std::endl;
}
else
{
std::cout << "CFileFind:"<< "文件查找成功" << std::endl;
std::cout << std::endl;
}
}
}
二、stat 函数
头文件
#include<sys/stat.h>
或者
#include<unistd.h>
函数原型
//**函数说明:**stat函数获取file_name指向文件的文件状态,并将文件信息保存到结构体buf中,
//执行成功返回0,失败返回-1,错误代码存于errno
int stat(const char * file_name, struct stat * buf)
//结构体struct stat的参数说明:
struct stat
{
dev_t st_dev; //device 文件的设备编号
ino_t st_ino; //inode 文件的索引节点
mode_t st_mode; //protection 文件的类型和存取的权限
nlink_t st_nlink; //number of hard links 连到该文件的硬连接数目, 刚建立的文件值为1.
uid_t st_uid; //user ID of owner 文件所有者的用户识别码
gid_t st_gid; //group ID of owner 文件所有者的组识别码
dev_t st_rdev; //device type 若此文件为装置设备文件, 则为其设备编号
off_t st_size; //total size, in bytes 文件大小, 以字节计算
unsigned long st_blksize; //blocksize for filesystem I/O 文件系统的I/O 缓冲区大小.
unsigned long st_blocks; //number of blocks allocated 占用文件区块的个数, 每一区块大小为512 个字节.
time_t st_atime; //time of lastaccess 文件最近一次被存取或被执行的时间, 一般只有在用mknod、utime、read、write 与tructate 时改变.
time_t st_mtime; //time of last modification 文件最后一次被修改的时间, 一般只有在用mknod、utime 和write 时才会改变
time_t st_ctime; //time of last change i-node 最近一次被更改的时间, 此参数会在文件所有者、组、权限被更改时更新
};
//st_mode说明:
1、S_IFMT 0170000 文件类型的位遮罩
2、S_IFSOCK 0140000 scoket
3、S_IFLNK 0120000 符号连接
4、S_IFREG 0100000 一般文件
5、S_IFBLK 0060000 区块装置
6、S_IFDIR 0040000 目录
7、S_IFCHR 0020000 字符装置
8、S_IFIFO 0010000 先进先出
9、S_ISUID 04000 文件的 (set user-id on execution)位
10、S_ISGID 02000 文件的 (set group-id on execution)位
11、S_ISVTX 01000 文件的sticky 位
12、S_IRUSR (S_IREAD) 00400 文件所有者具可读取权限
13、S_IWUSR (S_IWRITE)00200 文件所有者具可写入权限
14、S_IXUSR (S_IEXEC) 00100 文件所有者具可执行权限
15、S_IRGRP 00040 用户组具可读取权限
16、S_IWGRP 00020 用户组具可写入权限
17、S_IXGRP 00010 用户组具可执行权限
18、S_IROTH 00004 其他用户具可读取权限
19、S_IWOTH 00002 其他用户具可写入权限
20、S_IXOTH 00001 其他用户具可执行权限上述的文件类型在 POSIX 中定义了检查这些类型的宏定义
21、S_ISLNK (st_mode) 判断是否为符号连接
22、S_ISREG (st_mode) 是否为一般文件
23、S_ISDIR (st_mode) 是否为目录
24、S_ISCHR (st_mode) 是否为字符装置文件
25、S_ISBLK (s3e) 是否为先进先出
26、S_ISSOCK (st_mode) 是否为socket 若一目录具有sticky 位 (S_ISVTX), 则表示在此目录下的文件只能被该文件所有者、此目录所有者或root 来删除或改名.
举例
char cPath[128] = { 0 };
struct stat buff;
int nLen = UnicodeToChar(strPath, cPath, strPath.GetLength());
int nRet = -1;
if (nLen > 0)
{
nRet = stat(cPath, &buff);
if (0 == nRet ) //文件或者目录存在
{
if (S_IFREG & buff.st_mode)
{
//文件存在
std::cout << "stat:" << cPath << "文件查找成功" << std::endl;
std::cout << std::endl;
}
if (S_IFDIR & buff.st_mode)
{
//文件夹存在
std::cout << "stat:" << cPath << "文件夹查找成功" << std::endl;
std::cout << std::endl;
}
}
}
三、PathFileExists
头文件
#include <shlwapi.h>
#pragma comment(lib,"Shlwapi.lib") //如果没有这行,会出现link错误
功能
该函数可以检测文件或目录是否存在!
原型
BOOL PathFileExists ( __in LPCTSTR pszPath );
//Parameters参数pszPath[in] 类型:LPCTSTR,需要判断的文件或文件夹名
//存在该文件,则返回TRUE, 相反,返回FALSE.
举例
if (PathFileExists(strPath))
{
//文件或文件夹存在
std::cout << "PathFileExists:" << "文件或文件夹查找成功" << std::endl;
std::cout << std::endl;
}
四、CFileStatus
功能
获取指定文件的状态信息
参数
rStatus 要获取状态信息的 CFileStatus 结构的引用。 CFileStatus 结构具有下列字段:
CTime m_ctime 文件创建日期和时间。
CTime m_mtime 文件的上次更新的日期和时间。
CTime m_atime 文件用于读取最后访问的日期和时间。
ULONGLONG m_size 文件的逻辑大小(以字节为单位),如报告DIR命令。
BYTE m_attribute 文件的属性字节。
char m_szFullName[_MAX_PATH] 在Windows字符集的绝对文件名。
lpszFileName 在路径所需文件的Windows字符集的字符串。 路径可以是相对路径或绝对的,也可以包含网络路径名。
pTM 为CAtlTransactionManager对象的指针
返回值
如果指定的文件的状态信息成功获取,返回TRUE; 否则,FALSE。
说明
GetStatus 的非静态版本检索打开文件的状态信息与特定 CFile 对象。 GetStatus 的静态版本获取从特定文件路径的文件状态,而不会实际打开文件。 这将用于测试文件是否存在以及访问权限很有用。
CFileStatus 结构的 m_attribute 成员引用设置的文件属性。 CFile 选件类提供 Attribute 枚举类型,因此文件属性可以指定标记:
enum Attribute {
normal = 0x00,
readOnly = 0x01,
hidden = 0x02,
system = 0x04,
volume = 0x08,
directory = 0x10,
archive = 0x20
};
原型
BOOL GetStatus(
CFileStatus& rStatus
) const;
static BOOL PASCAL GetStatus(
LPCTSTR lpszFileName,
CFileStatus& rStatus,
CAtlTransactionManager* pTM = NULL
);
例子
CFileStatus FileStatus;
BOOL bFileExists = CFile::GetStatus(strPath, FileStatus);
if (bFileExists)
{
//文件或文件夹存在
std::cout << "CFileStatus:" << "文件或文件夹查找成功" << std::endl;
std::cout << std::endl;
}
五、access
头文件
unistd.h
或者
io.h
功能
access( )函数:用于文件读取,判断文件是否存在,并判断文件是否可写。Linux中,函数为access();标准C++中,该函数为_access,两者的使用方法基本相同
原型
access(const char *pathname, int mode);//位于<unistd.h>中
int _access(const char *pathname, int mode);//位于<io.h>中
pathname 为文件路径或目录路径 mode 为访问权限
如果文件具有指定的访问权限,则函数返回0;如果文件不存在或者不能访问指定的权限,则返回-1.
mode的值和含义如下所示:
00——只检查文件是否存在
02——写权限
04——读权限
06——读写权限
例子
nRet = _access(cPath, S_OK);
if (0 == nRet)
{
//文件或者文件夹存在
std::cout << "_access:" << cPath << "文件或文件夹查找成功" << std::endl;
std::cout << std::endl;
}
整体测试代码
void CIsFileExistDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CString strPath = _T("D:\\DemoTest\\IsFileExist\\IsFileExist");
//方法一:CFileFind
CFileFind fFile;
BOOL bRet = fFile.FindFile(strPath);
if (bRet)
{
std::cout << "CFileFind:" << "文件或者文件夹查找成功" << std::endl;
std::cout << std::endl;
while (bRet)
{
bRet = fFile.FindNextFile();
if (fFile.IsDots())
{
continue;
}
if (fFile.IsDirectory())
{
std::cout << "CFileFind:" << "文件夹查找成功" << std::endl;
std::cout << std::endl;
}
else
{
std::cout << "CFileFind:"<< "文件查找成功" << std::endl;
std::cout << std::endl;
}
}
}
//方法二:stat
char cPath[128] = { 0 };
struct stat buff;
int nLen = UnicodeToChar(strPath, cPath, strPath.GetLength());
int nRet = -1;
if (nLen > 0)
{
nRet = stat(cPath, &buff);
if (0 == nRet ) //文件或者目录存在
{
if (S_IFREG & buff.st_mode)
{
//文件存在
std::cout << "stat:" << cPath << "文件查找成功" << std::endl;
std::cout << std::endl;
}
if (S_IFDIR & buff.st_mode)
{
//文件夹存在
std::cout << "stat:" << cPath << "文件夹查找成功" << std::endl;
std::cout << std::endl;
}
}
}
//方式三:PathFileExists
if (PathFileExists(strPath))
{
//文件或文件夹存在
std::cout << "PathFileExists:" << "文件或文件夹查找成功" << std::endl;
std::cout << std::endl;
}
//方式四:CFileStatus
CFileStatus FileStatus;
BOOL bFileExists = CFile::GetStatus(strPath, FileStatus);
if (bFileExists)
{
//文件或文件夹存在
std::cout << "CFileStatus:" << "文件或文件夹查找成功" << std::endl;
std::cout << std::endl;
}
//方式五: access
//包含 io.h
nRet = _access(cPath, S_OK);
if (0 == nRet)
{
//文件或者文件夹存在
std::cout << "_access:" << cPath << "文件或文件夹查找成功" << std::endl;
std::cout << std::endl;
}
}
测试效果
如图:
1、当输入为目录
CString strPath = _T("D:\\DemoTest\\IsFileExist\\IsFileExist\\");
2、当输入为文件夹
CString strPath = _T("D:\\DemoTest\\IsFileExist\\IsFileExist");
2、当输入为文件
CString strPath = _T("D:\\DemoTest\\IsFileExist\\IsFileExist\\IsFileExistDlg.cpp");