判断已知的路径是指向目录还是文件,如果是目录,可以检测出是否存在指定格式(*.*)的文件。
- #include <iostream>
- #include <io.h>
- #include <fstream>
- #include <sys/stat.h>
-
- //判断路径是否有效/目录/文件
- int checkPath(const std::string strPath)
- {
- struct stat infos;
-
- if (stat(strPath.c_str(), &infos) != 0)
- {
- return -1; //无效
- }
- else if (infos.st_mode & S_IFDIR)
- {
- return 0; //目录
- }
- else if (infos.st_mode & S_IFREG)
- {
- //这里多写一个if 是为了记录一下判断条件
- return 1; //文件
- }
- else
- {
- return -1;
- }
- }
-
- //查找特定文件(以*.txt举例)
- bool checkfile(const std::string strPath, std::vector<std::string> &vecFileName)
- {
- struct _finddata_t fileinfo;
- intptr_t hFile;
- std::string strFilePath;
-
- strFilePath = strPath + "*.txt";
-
- if ((hFile = _findfirst(strFilePath.data(), &fileinfo)) == -1L)
- {
- //未找到指定类型的文件,返回false
- return false;
- }
-
- do
- {
- vecFileName.push_back(fileinfo.name);
- } while (_findnext(hFile, &fileinfo) == 0);
-
- _findclose(hFile);
-
- return true;
- }
-
- //查找目录下所有文件 -- 这个函数未验证,但理论上应该可行,有问题再更新
- bool checkallfile(const std::string strPath, std::vector<std::string> &vecFileName)
- {
- struct _finddata_t fileinfo;
- intptr_t hFile;
- std::string strFilePath;
-
- strFilePath = strPath.append("\\*.*");
-
- if ((hFile = _findfirst(strFilePath.data(), &fileinfo)) == -1L)
- {
- //未找到文件,返回false
- return false;
- }
-
- do
- {
- //if (fileinfo.attrib & _a_SUBDIR) //也可以通过这个条件判定判断是目录还是文件
-
- vecFileName.push_back(fileinfo.name);
- } while (_findnext(hFile, &fileinfo) == 0);
-
- _findclose(hFile);
-
- return true;
- }
实现上述的两个功能,用到两个特别关键的结构体:
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等
ino_t st_ino; //inode节点号
dev_t st_dev; //设备号码
dev_t st_rdev; //特殊设备号码
nlink_t st_nlink; //文件的连接数
uid_t st_uid; //文件所有者
gid_t st_gid; //文件所有者对应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //伟建内容对应的块数量
};
struct _finddata_t
{
unsigned attrib;
time_t time_create;
time_t time_access;
time_t time_write;
_fsize_t size;
char name[_MAX_FNAME];
};unsigned atrrib:
文件属性的存储位置。它存储一个unsigned单元,用于表示文件的属性。文件属性是用位表示的,主要有以下一些:_A_ARCH(存档)、 _A_HIDDEN(隐藏)、_A_NORMAL(正常)、_A_RDONLY(只读)、_A_SUBDIR(文件夹)、_A_SYSTEM(系统)。这些都是在源文件中定义的宏,可以直接使用,而本身的意义其实是一个无符号整型(只不过这个整型应该是2的几次幂,从而保证只有一位为 1,而其他位为0)。既然是位表示,那么当一个文件有多个属性时,它往往是通过位或的方式,来得到几个属性的综合。例如只读+隐藏+系统属性,应该为:_A_HIDDEN | _A_RDONLY | _A_SYSTEM 。
time_t time_create:
这里的time_t是一个变量类型,实际上就是长整形变量 long int,用来保存从1970年1月1日0时0分0秒到现在时刻的秒数
time_t time_access:文件最后一次被访问的时间。
time_t time_write:文件最后一次被修改的时间。
_fsize_t size:文件的大小(字节数表示)。
char name[_MAX_FNAME]:
文件的文件名。这里的_MAX_FNAME是一个常量宏,它在头文件中被定义,表示的是文件名的最大长度。
关键函数:
long _findfirst( char *filespec, struct _finddata_t *fileinfo );
返回值:如果查找成功的话,将返回一个long型的唯一的查找用的句柄。这个句柄将会在_findnext函数中被使用。失败返回-1.
参数:
filespec:标明文件的字符串,可支持通配符。比如:*.c,则表示当前文件夹下的所有后缀为C的文件。
fileinfo :这里就是用来存放文件信息的结构体的指针。这个结构体必须在调用此函数前声明,不过不用初始化,只要分配了内存空间就可以了。函数成功后,函数会把找到的文件的信息放入这个结构体所分配的内存空间中。
int _findnext( long handle, struct _finddata_t *fileinfo );
返回值:若成功返回0,否则返回-1。
参数:
handle:即由_findfirst函数返回回来的句柄。
fileinfo:文件信息结构体的指针。找到文件后,函数将该文件信息放入此结构体中。
int _findclose( long handle );
返回值:成功返回0,失败返回-1。
参数:
handle :_findfirst函数返回回来的句柄。
该结构体和搭配的函数使用的逻辑就是先用_findfirst查找第一个文件,若成功则用返回的句柄,调用_findnext函数查找其他的文件,当查找完毕后用,用_findclose函数结束查找。