C/C++遍历目录下的所有文件(Windows/Linux篇,超详细)
本文可转载,转载请注明出处:http://www.cnblogs.com/collectionne/p/6815924.html。
前面的一篇文章我们讲了用Windows API遍历一个目录下的所有文件,这次我们讲用一种Windows/Linux通用的方法遍历一个目录下的所有文件。
Windows/Linux的IDE都会提供一个头文件——<io.h>。看名字,似乎是关于I/O的,但是实际上它还提供了类似于WIN32_FIND_DATA、FindFirstFile()、FindNextFile()和FindClose()的查找文件的功能。
_finddata_t结构
_finddata_t结构用来记录查找到的文件的信息。实际上有_finddata32_t、_finddata32i64_t、_finddata64i32_t、_finddata64_t、_wfinddata32_t、_wfinddata32i64_t、_wfinddata64i32_t、_wfinddata64_t八个结构,但都只是在32位/64位整数和字符类型上有所区别,但整体上相同。大致定义如下(MSDN):
struct _finddata_t
{
unsigned attrib;
size_t time_create;
size_t time_access;
size_t time_write;
_fsize_t size;
char name[_MAX_PATH];
};
对于不同的_finddata_t结构,time_create、time_access和time_write的类型为_time32_t或_time64_t,size的类型为_fsize_t或__int64,name为char[_MAX_PATH]或wchar_t[_MAX_PATH]。
attrib
unsigned类型,文件属性。
time_create
_time32_t/_time64_t类型,文件创建时间(FAT文件系统为-1)。以UTC格式存储,如果需要转换成当地时间,使用localtime_s()。
time_access
_time32_t/_time64_t类型,文件最后一次被访问的时间(FAT文件系统为-1)。以UTC格式存储,如果需要转换成当地时间,使用localtime_s()。
time_write
_time32_t/_time64_t类型,文件最后一次被写入的时间。以UTC格式存储,如果需要转换成当地时间,使用localtime_s()。
size
_fsize_t/__int64类型,文件的长度(以字节为单位)。
name
char[_MAX_PATH]/wchar_t[_MAX_PATH]类型,文件/目录名,不包含路径。
对于不支持文件创建时间、文件上一次访问时间的文件系统,time_create和time_access为-1。
_MAX_PATH在stdlib.h中被定义为260。
一般_finddata_t被定义为_finddata32_t/_finddata64i32_t,_wfinddata_t被定义为_wfinddata32_t/_wfinddata64i32_t。为方便,下文中将_finddata_t和_wfinddata_t统称为_finddata_t。
文件属性常量
一个文件/目录可以有多种属性,每种属性可以是下面列出的属性之一。
_A_ARCH
档案。文件被BACKUP指令改变或清除时被设置。值:0x20。
_A_HIDDEN
隐藏。使用DIR指令一般看不到,除非使用/AH选项。值:0x02。
_A_NORMAL
普通。文件没有更多属性被设置,可以没有限制地被读或写。值:0x00。
_A_RDONLY
只读。不能以“写”为目的打开该文件,并且不能创建同名的文件。值:0x01。
_A_SUBDIR
子目录。值:0x10。
_A_SYSTEM
系统文件。使用DIR指令一般看不见,除非使用/A或/A:S选项。值:0x04。
要检查x是否含有某个属性a,可以用x & a进行检查。指定多个属性可以使用按位or运算符,例如_A_SYSTEM | _A_RDONLY | _A_HIDDEN。
通配符(wildcards)
遍历文件目录时需要使用通配符,详见我的另一篇文章。
_findfirst()/_findnext()/_findclose()函数
_findfirst()函数
intptr_t _findfirst(
const char * filespec,
struct _finddata_t *fileinfo
);
实际上_findfirst()有10个版本,这里只列出一个。
filespec
const char */const wchar_t *类型,目标文件说明(可包含通配符)。
fileinfo
_finddata_t *类型,函数将会填入文件/目录信息。
返回值
如果成功,返回一个唯一的搜索句柄标识一个或一组和filespec说明匹配的文件,可以用于接下来的_findnext()和_findclose()函数。否则_findfirst()返回-1。注意,intptr_t并不是指针类型,只是int或__int64的typedef。
_findnext()函数
int _findnext(
intptr_t handle,
struct _finddata_t *fileinfo
);
handle
intptr_t类型,搜索句柄。
fileinfo
_finddata_t *类型,函数将会填入文件/目录信息。
返回值
如果成功,返回0,否则返回-1。如果没有更多能够找到的文件了,也会导致失败。
_findclose()函数
int _findclose(
intptr_t handle
);
关闭搜索句柄并释放相应的资源。
handle
搜索句柄。
返回值
成功返回0,失败返回-1。
程序代码
1. 遍历目录下的所有文件
#include <iostream>
#include <cstring> // for strcat()
#include <io.h>
using namespace std; void listFiles(const char * dir); int main()
{
char dir[];
cout << "Enter a directory (ends with \'\\\'): ";
cin.getline(dir, ); strcat(dir, "*.*"); // 在要遍历的目录后加上通配符
listFiles(dir); return ;
} void listFiles(const char * dir)
{
intptr_t handle;
_finddata_t findData; handle = _findfirst(dir, &findData); // 查找目录中的第一个文件
if (handle == -)
{
cout << "Failed to find first file!\n";
return;
} do
{
if (findData.attrib & _A_SUBDIR
&& strcmp(findData.name, ".") ==
&& strcmp(findData.name, "..") ==
) // 是否是子目录并且不为"."或".."
cout << findData.name << "\t<dir>\n";
else
cout << findData.name << "\t" << findData.size << endl;
} while (_findnext(handle, &findData) == ); // 查找目录中的下一个文件 cout << "Done!\n";
_findclose(handle); // 关闭搜索句柄
}
程序遍历目录下的所有文件/目录,如果是文件则输出文件大小。
注意_findnext()函数成功返回0,因此要加上==0或!=-1进行判断,不能省略。
此外还有一个值得注意的地方:
if (findData.attrib & _A_SUBDIR
&& strcmp(findData.name, ".")
&& strcmp(findData.name, "..")
)
...
使用_findfirst()、_findnext()进行搜索时,可能会得到"."和".."两个文件夹名。这两个值可以忽略。
2. 遍历目录中的所有文件
注意是“目录中”而不是“目录下”,这个程序将会遍历一个目录里包含的所有文件。
#include <iostream>
#include <cstring> // for strcpy(), strcat()
#include <io.h> using namespace std; void listFiles(const char * dir); int main()
{
char dir[];
cout << "Enter a directory: ";
cin.getline(dir, ); listFiles(dir); return ;
} void listFiles(const char * dir)
{
char dirNew[];
strcpy(dirNew, dir);
strcat(dirNew, "\\*.*"); // 在目录后面加上"\\*.*"进行第一次搜索 intptr_t handle;
_finddata_t findData; handle = _findfirst(dirNew, &findData);
if (handle == -) // 检查是否成功
return; do
{
if (findData.attrib & _A_SUBDIR)
{
if (strcmp(findData.name, ".") == || strcmp(findData.name, "..") == )
continue; cout << findData.name << "\t<dir>\n"; // 在目录后面加上"\\"和搜索到的目录名进行下一次搜索
strcpy(dirNew, dir);
strcat(dirNew, "\\");
strcat(dirNew, findData.name); listFiles(dirNew);
}
else
cout << findData.name << "\t" << findData.size << " bytes.\n";
} while (_findnext(handle, &findData) == ); _findclose(handle); // 关闭搜索句柄
}
C/C++遍历目录下的所有文件(Windows/Linux篇,超详细)的更多相关文章
- C/C++遍历目录下的所有文件(Windows篇,超详细)
注: 1. 本文讨论的是怎么用Windows API遍历目录下的所有文件.除Windows API,还有一种Windows/Linux通用的方式,使用<io.h>. 2. 本文部分翻译自M ...
- windows 遍历目录下的所有文件 FindFirstFile FindNextFile
Windows下遍历文件时用到的就是FindFirstFile 和FindNextFile 首先看一下定义: HANDLE FindFirstFile( LPCTSTR lpFileName, // ...
- C 给定路径遍历目录下的所有文件
在此之前需要了解 WIN32_FIND_DATA的结构 以及 FindFirstFile. FindNextFile原型以及用法注意事项传送门如下 https://msdn.microsoft.co ...
- php 遍历目录下的所以文件和文件夹
<?php/** * 遍历文件夹和文件列 * @author lizhiming * @date 2016/06/30 */define('DS', DIRECTORY_SEPARATOR); ...
- 遍历目录下的所有文件-os.walk
#coding:utf-8 import os for root,dirs,files in os.walk("D:"): for fileItem in files: print ...
- shell 遍历目录下的所有文件
dir=/usr/local/nginx/logs for file in $dir/*; do echo $file done //结果 ./test.sh /usr/local/nginx/log ...
- shell编程--遍历目录下的文件
假定目录text下有如下文件 目录:dir_1.dir_2.dir_3 文件:text_1.text_2 遍历目录下所有的文件是目录还是文件 if -- if类型: #!bin/sh for ...
- C++遍历路径下的所有文件
intptr_t类型用于记录文件夹句柄,注意该类型不是指针类型,而是int型的重定义. _finddata_t结构体类型用于记录文件信息. _finddata_t结构体定义如下 struct _fin ...
- 复制D:\\day05目录下的所有文件到D:\\copy,并将.txt文件改为.java文件。
**解题思路: 1.首先定义一个静态的refile方法,参数传入两个文件路径 2.要复制目录下的所有文件,首先查询File类的方法,可以使用listFiles方法得到目录下的文件 3.想到这问题基本就 ...
随机推荐
- dubbo+zipkin调用链监控
分布式环境下,对于线上出现问题往往比单体应用要复杂的多,原因是前端的一个请求可能对应后端多个系统的多个请求,错综复杂. 对于快速问题定位,我们一般希望是这样的: 从下到下关键节点的日志,入参,出差,异 ...
- CSS选择器渲染效率
1 浏览器如何识别你的选择器 首先我们需要清楚,浏览器是如何读取选择器,以识别样式,并将相应的样式附于对应的HTML元素,达到美化页面的效果.Chris Coyier曾在<Efficiently ...
- (转)使用string.Format需要注意的一个性能问题
今天,我在写C#代码时,突然发现一个最熟悉的陌生人 —— string.Format.在写C#代码的日子里,与它朝夕相伴,却没有真正去了解它.只知道在字符串比较多时,用它比用加号进行字符串连接效率更高 ...
- Angular2.js——数据显示
显示数据,即属性绑定机制把数据显示到用户界面上. 在Angular中最典型的数据显示方式,就是把HTML模板中的控件绑定到Angular组件的属性. 接下来介绍几种数据显示的语法和代码片段. 使用插值 ...
- Win10或Win8下ObjectARX2015 Wizard向导创建项目失败解决方法
[原创]objectARX 2015 Wizard安装向导在Win8/win10下无法创建项目的解决方法总结by edata @2017-5-1objectARX 2015 Wizard安装向导在Wi ...
- ASP.Net MVC连接MySQL和Code First的使用
首先要准备一下的工具作为环境 MySQL Community Server 5.7.x My Workbench 6.3 VS2017 新建一个项目,NetMySQLCodeFirst 选择MVC,再 ...
- 根据优先关系矩阵使用逐次加一发构造优先函数(Java)
若已知运算符之间的优先关系,可按如下步骤构造优先函数: 1.对每个运算符a(包括#在内)令f(a)=g(a)=1 2.如果a⋗b且f(a)<=g(b)令f(a)=g(b)+1 3.如果a⋖b且f ...
- 微信小程序之购物车功能
前言 以往的购物车,基本都是通过大量的 DOM 操作来实现.微信小程序其实跟 vue.js 的用法非常像,接下来就看看小程序可以怎样实现购物车功能. 需求 先来弄清楚购物车的需求. 单选.全选和取消, ...
- 简单的3D图片轮播dome
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 如何将网站升级为HTTPS协议?
基本概念: HTTP: 是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准,用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少. HT ...