PkFile文件夹打包备份工具 源码 分享

hongwenjun 2012-11-25 09:23:50
PkFile 1.00 Copyright (c) Hongwenjun(蘭公子) 2012-11-28

Usage: PkFile.exe -p{打包路径} -o{输出文件} -e{正则公式}

示 例: PkFile.exe -pD:\我的照片 -oD:\Temp\backup.tar -e2012-11
可以打包指定目录2012年11月建立或修改的文件

直接修改配置文件 PACKAGE_FILE.ini 中的PATH和REGEX 参数,等价控制台输入参数

/***************** 就当使用说明吧 ^_^ *****************/

为什么写这个工具?这个工具有什么用?

我有一个工作目录,2004年存档以来已经有50GB了,我保存文件算是比较好了,
把文件做的尽量小了再保存。听一个同行说,他的工作数据现在已经有1TB多了。
我本来是使用同步软件双机备份,几个月同步一次,家里笔记本半年多和工作电脑
同步一次。想找个差异备份软件,好像找不到好。
所以就自己写了这个正则打包工具,为自己服务,和可能用的到人服务。

举个实例操作:我想把 2012年10月到12月数据打包成一个包,用U盘异地备份
连续输入以下三次命令
PkFile.exe -pD:\工作目录 -oD:\Temp\backup.tar -e2012-10
PkFile.exe -pD:\工作目录 -oD:\Temp\backup.tar -e2012-11
PkFile.exe -pD:\工作目录 -oD:\Temp\backup.tar -e2012-12

就会把 2012年10月到12月三个月的文件打包到 backup.tar
因为数据一般都是已经压缩过,用tar只打包,速度上会快很多

对于不习惯控制台操作的朋友,
PACKAGE_FILE.ini 只留三行
PATH = D:\工作目录
REGEX = 2012-10
PACKFILE = D:\Temp\backup.tar

然后双击 PkFile.exe 就可以备份了

/***************** PACKAGE_FILE.ini 文件示例 *************************
;直接修改配置文件 = PACKAGE_FILE.ini 中的PATH和REGEX 参数,等价控制台输入参数
[PACKAGE_FILE]
PATH = D:\工作目录
REGEX = 2012-10
PACKFILE = D:\Temp\backup.tar
***************************************************************************/

PkFile文件夹打包备份工具 软件和源码下载地址
http://srgb.googlecode.com/files/PACKAGE_FILE.7z
...全文
308 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
shuweiya 2013-12-23
  • 打赏
  • 举报
回复
有点用处的工具
hongwenjun 2012-12-04
  • 打赏
  • 举报
回复


由原来 调用 DIR 命令获得文件表
改成了 自己使用 WINAPI 获取文件表

现在应该能处理同名文件的问题了

http://code.google.com/p/srgb/source/diff?spec=svne1b77103c0e236cb61cf3698c19a8504e7b6bb31&r=e1b77103c0e236cb61cf3698c19a8504e7b6bb31&format=side&path=/PackageFile/main.cpp&old_path=/PackageFile/main.cpp&old=5640d5a1ccaf5a91031b3d562eba1a8690279784


PkFile 1.01 目录打包工具和源码 更新了源码
源码和Bin 下载地址
http://srgb.googlecode.com/files/PACKAGE_FILE_V1.1.7z
newtee 2012-12-03
  • 打赏
  • 举报
回复
我就来看看
hongwenjun 2012-12-03
  • 打赏
  • 举报
回复
#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 就好了....
hongwenjun 2012-11-28
  • 打赏
  • 举报
回复
PkFile 1.00 目录打包工具和源码 2012-11-28 更新了源码,增强灵活性 http://srgb.googlecode.com/files/PACKAGE_FILE_v1.7z 处理命令行参数函数
// 参数初始化
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();
}
hongwenjun 2012-11-26
  • 打赏
  • 举报
回复
解决同名文件提取错误 看来只好从date.txt 入手了
 驱动器 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 可用字节
转角天边 2012-11-25
  • 打赏
  • 举报
回复
再次感谢
hongwenjun 2012-11-25
  • 打赏
  • 举报
回复
实现处理 INI文件和命令行参数获得。 实际最后源码,添加了图标,分成了几个文件了,完善了细节了 花费的时间最长了, 完整代码 http://code.google.com/p/srgb/source/browse/PackageFile
#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;

}

转角天边 2012-11-25
  • 打赏
  • 举报
回复
学习,感谢楼主
hongwenjun 2012-11-25
  • 打赏
  • 举报
回复
DIR . /S /AA /B >\file.txt // 扫描出文件的绝对路径 // 使用公式(\w\:\\)(.*\\([^\\]+)) 匹配 D:\名片\89届初中毕业生通讯录.cdr 获得文件名和相对根目录的路径 regex re("(\\w\\:\\\\)(.*\\\\([^\\\\]+))"); 把两重数据都装入 MAP容器,遍历就能找出复合时间段的文件和路径了
#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;
}
hongwenjun 2012-11-25
  • 打赏
  • 举报
回复
在线源码地址: http://code.google.com/p/srgb/source/browse/PackageFile
#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

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧