本文介绍基于C++语言,遍历文件夹中的全部文件,并从中获取指定类型的文件的方法。

  首先,我们来明确一下本文所需实现的需求。现在有一个文件夹,其中包含了很多文件,如下图所示;我们如果想获取其中所有类型为.bmp格式的文件的名称,如果文件数量比较多的话,手动筛选就会很麻烦。而借助C++代码就可以简单地实现这一需求。如果需要借助Python代码来实现同样的需求,可以参考文章Python ArcPy批量掩膜、重采样大量遥感影像,基于其中提到的arcpy.ListRasters()函数来实现。

  首先需要说明的是,本文代码只能实现对某一文件夹下的文件进行遍历并筛选;如果是当前文件夹下的子文件夹中的文件,这一代码是没有办法遍历的。大家如果有相关需求的话,可以尝试在本文代码中加几个判断语句来实现;或者参考HDF格式遥感影像批量转为TIFF格式:ArcPy实现Python求取文件夹内的文件数量、子文件夹内的文件数量这两篇文章,基于其中提到的方法用Python代码来实现。

  本文分为两部分,第一部分为代码的分段讲解,第二部分为完整代码。

1 分段代码介绍

1.1 代码准备

  这一部分主要是代码的头文件、命名空间与我们自行撰写的自定义函数get_need_file()的声明;具体代码如下所示。

#include <iostream>
#include <vector>
#include <io.h> using namespace std; void get_need_file(string path, vector<string>& file, string ext);

  其中,由于我们在接下来的代码中需要用到容器vector这一数据类型,因此首先需要添加#include <vector>;同时,我们在接下来的代码中需要用到头文件io.h中的部分函数(主要都是一些与计算机系统、文件管理相关的函数),因此需要添加#include <io.h>

  接下来,这里声明了一个自定义函数get_need_file(),具体我们在本文1.3部分介绍。

1.2 主函数

  这一部分介绍代码的main()函数;具体代码如下所示。

int main() {
string file_path = R"(E:\02_Project\02_ChlorophyllProduce\01_Data\00_Test)";
vector<string> my_file;
string need_extension = ".bmp";
get_need_file(file_path, my_file, need_extension);
for (int i = 0; i < my_file.size(); i++)
{
cout << "File " << i+1 << " is:" << endl;
cout << my_file[i] << endl;
}
if (my_file.size() == 0)
{
cout << "No file can be found!" << endl;
}
else
{
cout << endl << "Find " << my_file.size() << " file(s)." << endl;
}
return 0;
}

  首先,我们定义了几个后续代码需要用到的变量。其中,file_path是一个字符串string变量,表示我们需要进行文件遍历的文件夹路径;这里我们用R"()"取消其中路径转义字符的使用。my_file是一个容器vector变量,其中将会存储我们需要筛选出来的特定文件。need_extension是我们需要筛选出来的特定文件的格式后缀。这些变量是如何工作的,具体我们在本文1.3部分介绍。

  随后,调用自定义函数get_need_file();调用完毕后,my_file中就存储了我们需要筛选出来的特定文件(如果有的话)。

  最后,for循环来输出我们找到的文件名称;if判断则是输出我们最终有没有筛选出指定格式的文件,如果筛选出来的话则会输出具体筛选出的文件数量。

  主函数部分整体比较简单,这里就不再赘述。

1.3 自定义函数

  这一部分介绍代码的自定义函数get_need_file(),也是本文最重要的部分;具体代码如下所示。

void get_need_file(string path, vector<string>& file, string ext)
{
intptr_t file_handle = 0;
struct _finddata_t file_info;
string temp;
if ((file_handle = _findfirst(temp.assign(path).append("/*" + ext).c_str(), &file_info)) != -1)
{
do
{
file.push_back(temp.assign(path).append("/").append(file_info.name));
} while (_findnext(file_handle, &file_info) == 0);
_findclose(file_handle);
}
}

  其中,自定义函数get_need_file()的三个参数,依次就是我们在主函数中定义的三个变量。

  在自定义函数get_need_file()中,我们首先定义了intptr_t类型的变量file_handle,并对其赋值为0。首先,这里的intptr_t是一种与计算机系统有关的数据类型,专门用来存放指针的地址;相较于用标准的int格式、long格式存储指针的地址,其具有更高的安全性,因此在计算机系统中通常用其存储指针的地址。其次,这里的file_handle表示文件句柄;在计算机系统中,每一个文件都有一个唯一的编号(相当于我们每一个人都有一个唯一的身份证号码),不同的文件具有不同的句柄,依据这一个句柄计算机系统就能锁定其对应的那个唯一的文件。因为文件句柄就是一个指向指针的指针,亦即指针的地址,因此我们就将其设定为intptr_t类型。此外,为其赋值为0,就是相当于先暂时随便给它赋一个肯定不对的数值,之后程序会自动替换。

  接下来,我们定义一个_finddata_t类型的变量file_info。首先,这里的_finddata_t其实是一个结构体,专门用来存储计算机系统中不同文件的各类信息;而file_info就是文件的不同信息。前面我们提到,file_handle相当于我们的身份证号码,那么这里file_info相当于就是存储了我们性别、家庭住址、爱好等信息的个人信息库。

  随后,我们再定义一个字符串string类型的变量temp,其用来存储临时生成的文件路径。

  接下来,进入if判断语句;这里我们将其拆开来看。首先,temp.assign(path).append("/*" + ext)其实就表示我们需要筛选的特定格式的文件,在本文中即E:\02_Project\02_ChlorophyllProduce\01_Data\00_Test)/*.bmp,并将其通过.assign()函数赋给字符串temp。随后,.c_str()函数将前面赋值好的字符串temp转为标准的C语言的格式(这是因为后面操作需要保证字符串为标准的C语言格式)。随后,将转换好的C语言格式字符串作为第一个参数,带入_findfirst()函数;其第二个参数则是file_info_findfirst()函数的功能是在当前路径下,找到与第一个参数(在这里也就是转换好的C语言格式字符串)相匹配的第一个文件;如果能找到这个文件,那么其就返回该文件的句柄,并将该文件的信息放入file_info;如果找不到这个文件,那么该函数就返回-1。因此,这里的if判断语句表示,一旦在当前路径下找到我们需要的文件,就继续进行接下来的代码;如果找不到需要的文件,那么相当于当前文件夹下就没有符合我们要求的文件。

  接下来,执行do语句内部的代码。其中,temp.assign(path).append("/").append(file_info.name)就表示当前找到的文件的路径及其名称,并通过push_back()函数将其附加至vector变量file的末尾。随后,进行while语句内部代码的判断——其中,_findnext()函数其实和前面的_findfirst()函数比较类似,它的作用是按照当前_findfirst()函数中所指定的文件筛选要求,进行继续筛选(_findfirst()函数相当于是找到了第一个符合我们筛选要求的文件,而_findnext()函数就是继续找,找到下一个符合要求的文件);如果其找到了,那么就将所找到的文件的句柄与信息返回到其两个参数中,且返回一个值0;如果没有找到的话就返回-1。因此,这里while语句相当于就是判断当前路径下还有没有我们需要的文件,如果有的话就再执行do语句内部的代码(即将文件的路径放入vector变量file的末尾);如果没有的话,那么就结束前面的循环。

  最后,_findclose()表示将当前句柄所表示的文件加以关闭,并将对应的文件资源释放。

2 完整代码

  本文所用到的全部代码如下。

#include <iostream>
#include <vector>
#include <io.h> using namespace std; void get_need_file(string path, vector<string>& file, string ext); int main() {
string file_path = R"(E:\02_Project\02_ChlorophyllProduce\01_Data\00_Test)";
vector<string> my_file;
string need_extension = ".bmp";
get_need_file(file_path, my_file, need_extension);
for (int i = 0; i < my_file.size(); i++)
{
cout << "File " << i + 1 << " is:" << endl;
cout << my_file[i] << endl;
}
if (my_file.size() == 0)
{
cout << "No file can be found!" << endl;
}
else
{
cout << endl << "Find " << my_file.size() << " file(s)." << endl;
}
return 0;
} void get_need_file(string path, vector<string>& file, string ext)
{
intptr_t file_handle = 0;
struct _finddata_t file_info;
string temp;
if ((file_handle = _findfirst(temp.assign(path).append("/*" + ext).c_str(), &file_info)) != -1)
{
do
{
file.push_back(temp.assign(path).append("/").append(file_info.name));
} while (_findnext(file_handle, &file_info) == 0);
_findclose(file_handle);
}
}

  运行上述代码后,将会得到所筛选出的文件各自的名称,以及其具体数量。

  至此,大功告成。

C++遴选出特定类型的文件或文件名符合要求的文件的更多相关文章

  1. c++--------获取某个路径下所有文件的文件名,读写TXT文件到新的文件

    好久没写io操作了,手生了好多,为了防止自己老年痴呆,最简单实用的c++代码也push上来吧, 环境:mac,xcode(注意mac环境下Windows的函数不能用) 功能:打开一个文件目录,把所有文 ...

  2. python 提取目录中特定类型的文件

    python使用‘os’和‘re’模块提取目录中特定类型的文件,这两个模都是安装python自带的,所以不需要安装. 思路: 使用os库lilstdir获取文件夹中的所有文件名,然后带上文件夹路径组合 ...

  3. Java用来进行批量文件重命名,批量提取特定类型文件

    原因: 因为在网上下载视频教程,有的名字特别长,一般都是机构或者网站的宣传,不方便直接看到视频的简介,所以做了下面的第一个功能. 因为老师发的课件中,文件夹太多,想把docx都放在同一个文件夹下面,一 ...

  4. Linux复制指定目录及子目录下特定类型的文件

    首先建立一个用于测试的目录,用'tree'命令查看其结构如下所示: 可见,目录中主要包含用于测试的*.txt文件和用于充当炮灰的*.tes文件 目标是保持当前的目录结构,只把txt文件复制出来 方法一 ...

  5. emeditor只显示特定类型的文件

    emeditor过滤文件类型,右侧资源管理器中只显示特定类型的文件,如只显示java,xml,txt,properties等文件,而不显示doc,jpg,xls等emeditor不能打开的文件. 右击 ...

  6. git设置只允许特定类型的文件

    git设置只允许特定类型的文件 # 忽略所有文件 * # 不忽略目录 !*/ # 不忽略文件.gitignore和*.foo !.gitignore !*.foo

  7. C++查找指定路径下的特定类型的文件

    转载:https://www.cnblogs.com/tinaluo/p/6824674.html 例子:找到C盘中所有后缀为exe的文件(不包括文件夹下的exe文件) #include<std ...

  8. 使用python遍历文件夹取出特定的字符串

    # -*- coding: utf-8 -* import re import os # 需要处理的文件夹路径(绝对路径) path = u"/Users/a140/Downloads/te ...

  9. 诠释Linux中『一切都是文件』概念和相应的文件类型

    导读 在 Unix 和它衍生的比如 Linux 系统中,一切都可以看做文件.虽然它仅仅只是一个泛泛的概念,但这是事实.如果有不是文件的,那它一定是正运行的进程. 要理解这点,可以举个例子,您的根目录( ...

  10. php 文件上传后缀名与文件类型对照表(几乎涵盖所有文件)

    网上有很多php文件上传的类,文件上传处理是php的一个特色(至少手册上是将此作为php特点来展示的,个人认为php在数组方面的优异功能更有特 色),学php的人都知道文件上传怎么做,但很多人在编程中 ...

随机推荐

  1. Spring EL 表达式

    本篇讲述了Spring Expression Language -- 即Spring3中功能丰富强大的表达式语言,简称SpEL. SpEL是类似于OGNL和JSF EL的表达式语言,能够在运行时构建复 ...

  2. 什么是 Serverless 架构?

    随着时间的推移,Serverless 架构变得越来越火热,凭借着极致弹性.按量付费.低成本运维等特性,在很多领域发挥着越来越重要的作用:机器学习领域在近些年也非常火热,并在越来越多的行业中得到应用. ...

  3. <vue 基础知识 6、条件判断标签v-if>

    代码结构 一.     01-v-if用法 1.效果 根据分数的不同展现不同的汉字 2.代码 01-v-if用法.html <!DOCTYPE html> <html lang=&q ...

  4. 【内核】深入分析内核panic(一)--内核问题的原因

    1 概述 linux内核包括进程管理.内存管理.中断管理.设备驱动.同步机制等各种模块,它们共同运行在一个共享的地址空间中,因此在运行中一旦出现问题,彼此之间可能具有千丝万缕的联系. 而且与用户态不同 ...

  5. vue中mixin作用

  6. 淘宝flexible.js源码分析

    下面三种情况都会刷新页面,都会触发load事件. 1.a标签的超链接. 2.F5或者刷新按钮(强制刷新) 3.前进后退按钮 但是火狐中,有个特点,有个"往返缓存",这个缓存中不仅保 ...

  7. shell脚本(4)-格式化输入

    一.read命令 1.概念: 默认接受键盘的输入,回车符代表输入结束 2.read命令选项 -p:打印信息 -t:限定时间 -s:不回显 -n:输入字符个数 3.举例说明 (1)模拟登录 [root@ ...

  8. 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.11.17)

    一.百度网盘SVIP超级会员共享账号 可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答. 我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免 ...

  9. Qt5.9 UI设计(六)——TitleBar功能实现

    前言 上一章介绍了ControlTreeWidget 与ControlTabWidget联动的功能,这一章我们将实现自定义 TitleBar 的功能 操作步骤 修改按键图标最大和最小值 右键按键图标, ...

  10. [转帖]ORACLE恢复神器之ODU/AUL/DUL

    https://www.cnblogs.com/oracle-dba/p/3873870.html 分享ORACLE数据库恢复神器之ODU.DUL和AUL工具. ODU:ORACLE DATABASE ...