33,311
社区成员
发帖
与我相关
我的任务
分享
#include <windows.h>
#include <stdio.h>
FILE* pf_path_file;
void find_path(char* lp_path)
{
// fprintf(p, "目录%s下的文件/n", lp_path);
HANDLE hFile; // windows对文件的操作首先要得到一个文件句柄
FILETIME ft; SYSTEMTIME st; // 文件时间 和 系统时间
WIN32_FIND_DATAA wfd; // WIN32_FIND_DATAA 是windows定义的查找文件的结构
char sz_path[256];
strcpy(sz_path, lp_path);
strcat(sz_path, "\\*.*");
hFile = FindFirstFile(sz_path, &wfd); // FindFirstFile函数查找一个文件,sz_path是要查找的文件名,可以是全路径或相对路径,也可以写通配符,如“c:/*.*”
if (hFile != INVALID_HANDLE_VALUE) {
while (FindNextFile(hFile, &wfd)) { // 利用第一次找到的文件句柄,继续寻找下个文件,如果找到下个文件,则函数填充wfd结构,并返回true
if (wfd.cFileName[0] == '.')continue; // . 当前目录 .. 上级目录符号 跳过去
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // 判断,得出找到的文件名是否是一个文件夹,如果是,则递归调用查找函数,由此实现深度全文件夹搜索
strcpy(sz_path, lp_path);
strcat(sz_path, "\\");
strcat(sz_path, wfd.cFileName);
find_path(sz_path); // 低谷递归查找
} else {
ft = wfd.ftLastWriteTime;
FileTimeToSystemTime(&ft, &st);
printf("%d-%02d-%02d %02d:%02d ", st.wYear, st.wMonth, st.wDay, st.wHour + 8, st.wMinute);
printf("%10u | %s | %s\n", wfd.nFileSizeLow , wfd.cFileName , lp_path );
// fprintf(pf_path_file , "%u , %s , %s\n", wfd.nFileSizeLow , wfd.cFileName , lp_path);
}
}
}
}
int main(int argc, char* argv[])
{
pf_path_file = fopen("asd.txt", "w");
char sz_path[12] = "D:\\雅2010"; // 如果"c:" 设定默认盘符,
find_path(sz_path); // 搜索盘符或者路径,包括子目录
fclose(pf_path_file);
return 0;
}
准备用 WINAPI 搜索文件和路径
相关文章
http://bbs.csdn.net/topics/340009854
收藏 获取指定目录下的文件信息...输出到txt
文件属性的获取与更改:
一、 引言
文件是数据在磁盘上最常用的一种存放形式,也是在程序设计中与之经常打交道的一种编程对象,不少程序尤其是数据传输和处理类的应用程序更是需要频繁的创建、读取和写入文件。对于一些要求不是很严格的程序,我们往往只关心文件的内容是否正确、文件大小是否有增减或是再严格一些,看文件名是否符合规定等等。以上这些要素对于大多数程序而言显然是可以满足实际需求的,但对于某些特殊行业的一些有着比较严格要求的软件系统,仅有以上要素还是远远不够的,往往还需要对文件的所有属性诸如文件的创建时间、文件的最后访问时间、文件的最后修改时间等等进行提取处理与重新设置。
二、 WIN32_FIND_DATA结构
关于文件的全部属性信息,总计有以下以下9种:文件的标题名、文件的属性(只读、存档,隐藏等)、文件的创建时间、文件的最后访问时间、文件的最后修改时间、文件大小的高位双字、文件大小的低位双字、保留、保留。在这里只有文件标题名和文件的长度可以通过CFile类比较方便的获得,而对于其他几种属性的获取和设置就无能为力了。
在用findfirst()和findnext()函数去查找磁盘文件时经常使用的一个数据结构WIN32_FIND_DATA的成员变量里包含了以上所有的文件属性,因此可以通过这个结构作为获取和更改文件属性的手段。该结构的内容如下:
typedef struct _WIN32_FIND_DATA {
DWORD dwFileAttributes; //文件属性
FILETIME ftCreationTime; // 文件创建时间
FILETIME ftLastAccessTime; // 文件最后一次访问时间
FILETIME ftLastWriteTime; // 文件最后一次修改时间
DWORD nFileSizeHigh; // 文件长度高32位
DWORD nFileSizeLow; // 文件长度低32位
DWORD dwReserved0; // 系统保留
DWORD dwReserved1; // 系统保留
TCHAR cFileName[ MAX_PATH ]; // 长文件名
TCHAR cAlternateFileName[ 14 ]; // 8.3格式文件名
} WIN32_FIND_DATA, *PWIN32_FIND_DATA;
可以通过FindFirstFile()函数根据当前的文件存放路径查找该文件来把待操作文件的相关属性读取到WIN32_FIND_DATA结构中去:
WIN32_FIND_DATA ffd ;
HANDLE hFind = FindFirstFile("c:\\test.dat",&ffd);
在使用这个结构时不能手工修改这个结构中的任何数据,结构对于开发人员来说只能作为一个只读数据,其所有的成员变量都会由系统完成填写。在MSDN帮助中可以查找到关于WIN32_FIND_DATA结构的更加详细的说明。
三、 文件属性信息的获取与更改
为了更好的保存获取到的文件属性信息,对应于文件属性构造一个自定义的FILE_INFO数据结构,获取的属性信息可暂存于此:
typedef struct _FILE_INFO {
TCHAR szFileTitle[128]; //文件的标题名
DWORD dwFileAttributes; //文件的属性
FILETIME ftCreationTime; //文件的创建时间
FILETIME ftLastAccessTime; //文件的最后访问时间
FILETIME ftLastWriteTime; //文件的最后修改时间
DWORD nFileSizeHigh; //文件大小的高位双字
DWORD nFileSizeLow; //文件大小的低位双字
DWORD dwReserved0; //保留,为0
DWORD dwReserved1; //保留,为0
} FILE_INFO, * PFILE_INFO;
首先用FindFirstFile()函数将文件属性获取到WIN32_FIND_DATA 结构对象FindFileData中去,之后可以用FindClose()将其关闭,并把FindFileData中的有关文件属性信息的内容复制到自定义结构FILE_INFO的结构对象FileInfo中备用。下面是关于这部分描述的部分关键代码:
//声明结构对象
FILE_INFO FileInfo;
WIN32_FIND_DATA FindFileData;
……
//获取文件属性信息
FindClose(FindFirstFile("Test.txt",&FindFileData));
memset(&FileInfo,0,sizeof(FILE_INFO));
……
//将文件属性信息保存到FileInfo中备用
strcpy(FileInfo.szFileTitle,myFile.GetFileTitle());
FileInfo.dwFileAttributes = FindFileData.dwFileAttributes;
FileInfo.ftCreationTime = FindFileData.ftCreationTime;
FileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime;
FileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime;
FileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh;
FileInfo.nFileSizeLow = FindFileData.nFileSizeLow;
……
在获取到文件的原始属性信息后既可以原封不动的将属性重新写到文件,也可以对其中某一项或某几项属性内容进行修改后再行写入文件,从而达到更改文件属性的目的。比如可以用SetFileTime()函数设置文件的创建时间、最近一次访问时间以及最近一次修改的时间等等:
SetFileTime((HANDLE)destFile.m_hFile, //待写入的文件句柄
&FileInfo.ftCreationTime, //文件的创建时间
&FileInfo.ftLastAccessTime, //文件最近一次的访问时间
&FileInfo.ftLastWriteTime); //文件最近一次的修改时间
也可以用SetFileAttributes() 函数实现对文件属性的修改:
SetFileAttributes(FileInfo.szFileTitle,FileInfo.dwFileAttributes);
至于文件名的修改则更加简单,直接在创建文件时在CreateFile()或CFile类的成员函数Open里直接对文件名参数进行设置即可。
小结:本文通过对WIN32_FIND_DATA结构和SetFileTime()、SetFileAttributes()等主要函数实现了对磁盘文件的相关属性信息的获取与修改。用此技术可以在通讯等对文件有严格要求的应用领域实现文件全部信息(包括文件内容、文件名以及文件属性等)的完整传送。本文所述程序在Windows 98下由Microsoft Visual C++ 6.0编译调试通过。
#include "stdafx.h"
#include <windows.h>
#define FILEILTER "*.*"
BOOL IsRoot(LPCTSTR lpszPath)
{
TCHAR szRoot[4];
wsprintf(szRoot, "%c:\\", lpszPath[0]);
return (lstrcmp(szRoot, lpszPath) == 0);
}
void FindInAll(LPCTSTR lpszPath)
{
TCHAR szFind[MAX_PATH];
lstrcpy(szFind, lpszPath);
if (!IsRoot(szFind))
lstrcat(szFind, "\\");
lstrcat(szFind, FILEILTER); // 找所有文件
WIN32_FIND_DATA wfd;
HANDLE hFind = FindFirstFile(szFind, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
return;
do
{
if (wfd.cFileName[0] == '.')
continue; // 过滤这两个目录
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
TCHAR szFile[MAX_PATH];
if (IsRoot(lpszPath))
wsprintf(szFile, "%s%s", lpszPath, wfd.cFileName);
else
{
wsprintf(szFile, "%s\\%s", lpszPath, wfd.cFileName);
FindInAll(szFile); // 如果找到的是目录,则进入此目录进行递归
}
}
else
{
TCHAR szFile[MAX_PATH];
if (IsRoot(lpszPath))
{
wsprintf(szFile, "%s%s", lpszPath, wfd.cFileName);
}
else
{
wsprintf(szFile, "%s\\%s", lpszPath, wfd.cFileName);
printf("%s\n",szFile);
}
// 对文件进行操作
}
} while (FindNextFile(hFind, &wfd));
FindClose(hFind); // 关闭查找句柄
}
int main(int argc, char* argv[])
{
FindInAll("C:\\TEST");
return 0;
}
把两部分的功能合成一下,然后把结果输出到 txt 就好了....
// 参数初始化
int initial_arg(int argc , char* argv[])
{
GetAppDir(ConfigFile);
strcat(ConfigFile, "\\PACKAGE_FILE.ini");
if (IsFileExist(ConfigFile))
LoadConfigFile();
for (int i = 1 ; i != argc; ++i) {
const char* parg = argv[i];
if (*parg == '-') {
switch (* (parg + 1)) {
case 'p': case 'P':
Path_Argv = string(parg + 2); // 扫描路径参数
break;
case 'e': case 'E':
Reg_Argv = string(parg + 2); // 正则参数
break;
case 'o': case 'O':
Packfile_Argv = string(parg + 2); // 输出文件参数
break;
case 'd': case 'D':
Direct_Datelog_Flag = false; // 重新扫描目录
Delete_Datelog_Flag = true; // 完成后删除扫描记录 date.txt
break;
case 'l': case 'L':
Test_List_Flag = true; // 只是显示 listfiel.txt, 不打包文件
break;
case 'h': case 'H':
print_help(); // 调用帮助
return 88;
break;
default:
break;
}
}
}
// printf("%s\n%s\n%s\n", ConfigFile, Path_Argv.data() , Reg_Argv.data()) ;
return 0 ;
}
读取 配置文件函数
// 读取和保存配置
void LoadConfigFile()
{
string line;
fstream file(ConfigFile , fstream::in);
while (getline(file , line)) {
// 跳过没有'='号 和 有';' 的注解行
if (line.find('=') == string::npos)
continue ;
line = strTrim(line);
if (line[0] == ';')
continue ;
// 获得路径和正则公式( 截取 = 符号之后,删除空白)
if (line.find("PATH") != string::npos) {
line = line.substr(line.find('=') + 1);
Path_Argv = strTrim(line);
} else if (line.find("REGEX") != string::npos) {
line = line.substr(line.find('=') + 1);
Reg_Argv = strTrim(line);
} else if (line.find("PACKFILE") != string::npos) {
line = line.substr(line.find('=') + 1);
Packfile_Argv = strTrim(line);
} else if (line.find("DIRECTDATE") != string::npos) {
line = line.substr(line.find('=') + 1);
// 如果有date.txt ,不用每次扫描目录,如果更新了,手工删除date.txt
char df_path[MAX_PATH] = {0}; GetAppDir(df_path); strcat(df_path , "\\date.txt");
Direct_Datelog_Flag = (strTrim(line) == "1") && (IsFileExist(df_path));
}
}
file.close();
}
驱动器 R 中的卷是 RamDisk-PAE
卷的序列号是 1234-5678
R:\chrome 的目录
2012-11-01 04:01 700,833 chrome_100_percent.pak
2012-11-01 04:01 500,327 chrome_touch_100_percent.pak
2012-11-01 04:01 4,802,707 resources.pak
2012-11-01 06:15 460,312 ppgooglenaclpluginchrome.dll
2012-11-01 04:01 81,768 xinput1_3.dll
2012-11-09 15:25 0 First Run
2012-11-26 20:31 0 date.txt
28 个文件 82,137,577 字节
R:\chrome\Locales 的目录
2012-11-01 04:01 194,893 en-US.pak
2012-11-01 04:01 188,943 zh-CN.pak
2012-11-01 06:14 8,728 en-US.dll
2012-11-01 06:14 8,728 zh-CN.dll
4 个文件 401,292 字节
R:\chrome\VisualElements 的目录
2012-11-01 04:01 5,228 logo.png
2012-11-01 04:01 11,251 smalllogo.png
2012-11-01 04:01 12,428 splash-620x300.png
3 个文件 28,907 字节
R:\chrome\default_apps 的目录
2012-11-01 04:01 25,561 drive.crx
2012-11-01 04:01 24,040 gmail.crx
2012-11-01 04:01 26,392 search.crx
2012-11-01 04:01 23,668 youtube.crx
2012-11-01 04:01 870 external_extensions.json
5 个文件 100,531 字节
R:\chrome\Extensions 的目录
2012-11-01 04:01 99 external_extensions.json
1 个文件 99 字节
R:\chrome\PepperFlash 的目录
2012-11-01 04:01 1,986 manifest.json
2012-11-01 06:15 12,455,448 pepflashplayer.dll
2 个文件 12,457,434 字节
所列文件总数:
43 个文件 95,125,840 字节
0 个目录 4,714,692,608 可用字节
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <fstream>
#include <cstdio>
#include <cctype>
#include <regex>
#include <windows.h>
using namespace std;
// 简单的文件属性结构
struct F_STRUCT {
char date[16];
char time[16];
char size[255];
char name[255];
};
// 全局变量
char ConfigFile[MAX_PATH] = {0};
char AppPath[MAX_PATH] = {0};
string Path_Argv;
string Reg_Argv;
// 删除字符串前后空白
string strTrim(string& str)
{
str = str.substr(str.find_first_not_of("\t \n"));
str = str.substr(0, str.find_last_not_of("\t \n") + 1);
return str;
}
// 读取和保存配置
void LoadConfigFile()
{
string line;
fstream file(ConfigFile , fstream::in);
while (getline(file , line)) {
// 跳过没有'='号 和 有';' 的注解行
if (line.find('=') == string::npos)
continue ;
line = strTrim(line);
if (line[0] == ';')
continue ;
// 获得路径和正则公式( 截取 = 符号之后,删除空白)
if (line.find("PATH") != string::npos) {
line = line.substr(line.find('=') + 1);
Path_Argv = strTrim(line);
} else if (line.find("REGEX") != string::npos) {
line = line.substr(line.find('=') + 1);
Reg_Argv = strTrim(line);
}
}
file.close();
}
/***************** PACKAGE_FILE.ini 文件示例 *************************
;PkFile 1.00 Copyright (c) Hongwenjun(蘭公子) 2012-11-28
;
;Usage: PkFile.exe -p{打包路径} -e{正则公式}
;
;示 例:PkFile.exe -pD:\我的照片 -e2012-11
; 可以打包指定目录2012年11月建立或修改的文件
;直接修改配置文件 = PACKAGE_FILE.ini 中的PATH和REGEX 参数,等价控制台输入参数
[PACKAGE_FILE]
PATH = D:\我的照片\测试目录
; PATH = D:\我的照片\测试目录
REGEX = 2005-\d\d-\d\d
; REGEX = 2005-\d\d-\d\d
***************************************************************************/
// 检查一个文件是否存在
BOOL IsFileExist(LPCTSTR lpFileName)
{
WIN32_FIND_DATA fd = {0};
HANDLE hFind = FindFirstFile(lpFileName, &fd);
if (hFind != INVALID_HANDLE_VALUE) {
FindClose(hFind);
}
return ((hFind != INVALID_HANDLE_VALUE) && !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
}
// 功能 获得当前路径
char* GetAppDir(char* szPath)
{
char* ret = szPath;
GetModuleFileName(NULL, szPath, MAX_PATH); // 得到当前执行文件的文件名(包含路径)
*(strrchr(szPath , '\\')) = '\0'; // 删除文件名,只留下目录
return ret;
}
/** TODO (hongwenjun#1#): 现在不能处理文件名重名问题
实现了读取配置文件INI,识别注释语句
*/
int main(int argc , char* argv[])
{
GetAppDir(ConfigFile);
strcat(ConfigFile, "\\PACKAGE_FILE.ini");
if (IsFileExist(ConfigFile))
LoadConfigFile();
printf("%s\n", ConfigFile);
// 输入文件 D:\\名片\\date.txt D:\\名片\\file.txt
// DIR . /S /AA /TW >\date.txt 和 DIR . /S /AA /B >\file.txt
ifstream datefile("\\date.txt ");
ifstream pathfile("\\file.txt ");
ofstream listfile("\\listfile.txt");
for (int i = 1 ; i != argc; ++i) {
const char* parg = argv[i];
if (*parg == '-') {
switch (* (parg + 1)) {
case 'p':
Path_Argv = string(parg + 2); // 扫描路径参数
break;
case 'e':
Reg_Argv = string(parg + 2); ; // 正则参数
break;
default:
break;
}
}
}
printf("%s\n%s\n", Path_Argv.data() , Reg_Argv.data()) ; // app.exe -pD:\CodeBlocks -e\w+\.dll
string readline; // 读取每行,然后使用正则搜索匹配
smatch m;
regex e(Reg_Argv);
regex re("(\\w\\:\\\\)(.*\\\\([^\\\\]+))"); // 公式(\w\:\\)(.*\\([^\\]+)) 匹配 D:\名片\89届初中毕业生通讯录.cdr
F_STRUCT d_file ; // 简单的文件属性结构
map<string, string> mss_date;
map<string, string> mss_path;
while (getline(datefile , readline)) {
if (regex_search(readline, m, e)) { // 符合条件的的文件列表存如容器
sscanf(readline.c_str(), "%s %s %s" , d_file.date, d_file.time , d_file.size);
sprintf(d_file.name , "%s" , readline.c_str() + 36); // 为了处理文件名有空格,所以只好分两行读
// cout << d_file.name << " -> " << d_file.date << endl;
mss_date.insert(make_pair(string(d_file.date) + " -> " + d_file.name , string(d_file.name)));
}
}
while (getline(pathfile , readline)) {
if (regex_match(readline, m, re)) { // regex_match 和 regex_search 这里都可以用
// cout << m[3] << " -> " << m[2] << endl;
mss_path.insert(make_pair(m[3], m[2])); // 文件名 和 路径装载到容器
}
}
for (auto it = mss_date.begin() ; it != mss_date.end(); ++it) {
// cout << mss_path[it->second] << endl;
listfile << mss_path[it->second] << endl; // 输出结果
}
datefile.close(); pathfile.close(); listfile.close();
system("pause");
// system("7z a -ttar -r -scsWIN \\backup.tar @\\listfile.txt"); // 调用7z命令行打包文件
return 0;
}
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <fstream>
#include <cstdio>
#include <cctype>
#include <regex>
struct F_STRUCT { // 简单的文件属性结构
char date[16];
char time[16];
char size[255];
char name[255];
};
using namespace std;
int main(int argc , char* argv[])
{
// 输入文件 D:\\名片\\date.txt D:\\名片\\file.txt
// DIR . /S /AA /TW >\date.txt 和 DIR . /S /AA /B >\file.txt
ifstream datefile("/date.txt ");
ifstream pathfile("/file.txt ");
ofstream listfile("/listfile.txt");
string path_argv = "D:\\名片";
string reg_argv = "2010-\\d\\d-\\d\\d" ;// 2010-06-30 16:51 20,780 89届初中毕业生通讯录.cdr
for (int i = 1 ; i != argc; ++i) {
const char* parg = argv[i];
if (*parg == '-') {
switch (* (parg + 1)) {
case 'p':
path_argv = string(parg + 2); // 扫描路径参数
break;
case 'e':
reg_argv = string(parg + 2); ; // 正则参数
break;
default:
break;
}
}
}
cout << path_argv << reg_argv ; // app.exe -pD:\CodeBlocks -e\w+\.dll
string readline; // 读取每行,然后使用正则搜索匹配
smatch m;
regex e(reg_argv);
regex re("(\\w\\:\\\\)(.*\\\\([^\\\\]+))"); // 公式(\w\:\\)(.*\\([^\\]+)) 匹配 D:\名片\89届初中毕业生通讯录.cdr
/** TODO (hongwenjun#1#): 现在不能处理文件名重名问题 */
F_STRUCT d_file ; // 简单的文件属性结构
map<string, string> mss_date;
map<string, string> mss_path;
while (getline(datefile , readline)) {
if (regex_search(readline, m, e)) { // 符合条件的的文件列表存如容器
sscanf(readline.c_str(), "%s %s %s" , d_file.date, d_file.time , d_file.size);
sprintf(d_file.name , "%s" , readline.c_str() + 36); // 为了处理文件名有空格,所以只好分两行读
// cout << d_file.name << " -> " << d_file.date << endl;
mss_date.insert(make_pair(string(d_file.date) + " -> " + d_file.name , string(d_file.name)));
}
}
while (getline(pathfile , readline)) {
if (regex_match(readline, m, re)) { // regex_match 和 regex_search 这里都可以用
// cout << m[3] << " -> " << m[2] << endl;
mss_path.insert(make_pair(m[3], m[2])); // 文件名 和 路径装载到容器
}
}
for (auto it = mss_date.begin() ; it != mss_date.end(); ++it) {
cout << mss_path[it->second] << endl;
listfile << mss_path[it->second] << endl; // 输出结果
}
datefile.close(); pathfile.close(); listfile.close();
// system("7z a -ttar -r -scsWIN \\backup.tar @\\listfile.txt"); // 调用7z命令行打包文件
return 0;
}
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <fstream>
#include <cstdio>
#include <cctype>
#include <regex>
struct F_STRUCT { // 简单的文件属性结构
char date[16];
char time[16];
char size[255];
char name[255];
};
using namespace std;
int main(int argc , char* argv[])
{
// 输入文件 D:\\名片\\date.txt D:\\名片\\file.txt
// DIR . /S /AA /TW >date.txt 和 DIR . /S /AA /B >file.txt
ifstream datefile("D:\\名片\\date.txt ");
string readline; // 读取每行,然后使用正则搜索匹配
smatch m;
regex e("20\\d\\d-\\d\\d-\\d\\d"); // 2010-06-30 16:51 20,780 89届初中毕业生通讯录.cdr
F_STRUCT d_file ; // 简单的文件属性结构
map<string, string> mss;
while (getline(datefile , readline)) {
if (regex_search(readline, m, e)) { // 符合条件的的文件列表存如容器
sscanf(readline.c_str(), "%s %s %s" , d_file.date, d_file.time , d_file.size);
sprintf(d_file.name , "%s" , readline.c_str() + 36); // 为了处理文件名有空格,所以只好分两行读
// cout << d_file.name << " -> " << d_file.date << endl;
mss.insert(make_pair(string(d_file.date) + " -> " + d_file.name , string(d_file.name)));
}
}
for (auto it = mss.begin() ; it != mss.end(); ++it)
cout << it->first << endl;
return 0;
}
控制台 使用 DIR . /S /AA /TW >date.txt 输出文件
正则公式,搜索符号条件的记录行
regex e("20\\d\\d-\\d\\d-\\d\\d");
// 2010-06-30 16:51 20,780 89届初中毕业生通讯录.cdr