zoukankan      html  css  js  c++  java
  • [C/C++][文件操作] 对比目录并列出同名较新文件、较旧文件 0.1

    作者 523066680@163.com,转载请注明出处:[C/C++][文件操作]目录/文件夹对比并列出同名较新文件、较旧文件 V1

    主要是模仿robocopy的部分功能

    (robocopy /L 参数可以列出本地目录和备份目录中的异同之处,主要是标记出:较新的、较旧的、多出的文件 )

    现在还不会写GUI,打算后面自己做目录树diff,可以手动点选要复制的文件。

    同时我也知道有现成的软件,比如meld,但是windows下面不太好用。

    特性:

    一、支持Unicode字符路径

    二、使用了WriteConsoleW函数屏幕输出以保留Unicode字符完整性

    (虽然终端上有些Unicode字符看不到,但是标记、粘贴到别的编辑器上面是完整的,至少不会变成问好)

    如果是用 wprintf 或者转GBK再printf,则Unicode字符会丢失。

    三、判断为当前输出为重定向时,切换到WriteFile函数输出到指定的文件。这一点是因为WriteConsoleW

    输出的信息不支持直接重定向,好在conio.h提供了判断输出环境的方法。

    这里感谢 flyue 在"终端输出Unicode字符、重定向、标记复制" 方面的指教

    编译备注:为了方便Unicode模式,用了 wmain做入口函数,使用mingw g++编译时,加上 -municode 参数,

    否则会提示 winMain 未定义。在stackoverflow看到的解决方法。

    本来vc的 cl.exe 也可以直接编译,但是居然默认不带dirent.h ... windows有另外一套API,也罢

    等我学会了再写一个API的版本。

      1 /*
      2    g++ CompareW.cpp -municode -o CompareW
      3 */
      4 
      5 #include <cstdio>
      6 #include <cstdlib>
      7 #include <cwchar>
      8 #include <cstring>
      9 #include <clocale>
     10 #include <fcntl.h>
     11 #include <sys/stat.h>
     12 #include <sys/types.h>
     13 #include <dirent.h>
     14 #include <windows.h>
     15 #include <io.h>
     16 
     17 #define NAME_MAX 1024
     18 
     19 void func(
     20     wchar_t path[], 
     21     const wchar_t dir_a[], 
     22     const wchar_t dir_b[]
     23     );
     24 
     25 bool FileExists(const wchar_t *wpath);
     26 bool FolderExists(const wchar_t *wpath);
     27 
     28 void console_print(const wchar_t str[]);
     29 void CheckConsoleRedirect(void);
     30 
     31 void PATH_A_TO_B (
     32     const wchar_t source[], 
     33     const wchar_t a[], 
     34     const wchar_t b[], 
     35           wchar_t newstr[]
     36     );
     37 
     38 DWORD written = 0;
     39 static bool g_bRedirect = false;
     40 
     41 int wmain(int argc, wchar_t *argv[] ) 
     42 {
     43     setlocale( LC_ALL, ".936" );
     44     CheckConsoleRedirect();
     45 
     46     if (argc > 2)
     47     {
     48         if (  _wopendir(argv[1]) && _wopendir(argv[2])  ) 
     49         {
     50             func( argv[1], argv[1], argv[2]);
     51             //wprintf(L"B
    ");
     52             //func( argv[2], argv[2], argv[1]);
     53 
     54             fprintf(stderr, "All is done!");
     55         }
     56         else
     57         {
     58             fprintf(stderr, "Argument is not correct!");
     59         }
     60     }
     61     else
     62     {
     63         fprintf(stderr, "Arguments not enough!");
     64     }
     65     
     66     return 0;
     67 }
     68 
     69 void func(
     70     wchar_t path[], 
     71     const wchar_t dir_a[], 
     72     const wchar_t dir_b[]
     73     )
     74 {
     75     _WDIR * a = _wopendir(path);
     76     _wdirent * dp;
     77     _WDIR * aa;
     78     struct stat stA;
     79     struct stat stB;
     80 
     81     wchar_t fullpath[NAME_MAX] = L"";
     82 
     83     while (dp = _wreaddir(a))
     84     {
     85         if ( 
     86                wcscmp(dp->d_name, L".") == 0 
     87             || wcscmp(dp->d_name, L"..") == 0  
     88         )
     89         {
     90             continue;
     91         }
     92 
     93         swprintf(fullpath, L"%ls\%ls", path, dp->d_name);
     94         wstat(fullpath, &stA);
     95 
     96         if ( (stA.st_mode & S_IFMT) == S_IFDIR )
     97         {
     98             func( fullpath, dir_a, dir_b );
     99         }
    100         else
    101         {
    102             wchar_t full_info[NAME_MAX + 32] = L"";
    103             wchar_t mt_str[20] = L"";
    104             wchar_t trypath[1024] = L"";
    105 
    106             //swprintf(full_info, L"%ld	%ls
    ", stA.st_mtime, fullpath );
    107             PATH_A_TO_B( fullpath, dir_a, dir_b, trypath );
    108             if ( ! FileExists(trypath) )
    109             {
    110                 swprintf(full_info, L"%8ls : %ls
    ", L"Extra", fullpath );
    111                 console_print( full_info );
    112             } 
    113             else
    114             {
    115                 wstat(trypath, &stB);
    116                 if (stA.st_mtime > stB.st_mtime )
    117                 {
    118                     swprintf(full_info, L"%8ls : %ls
    ", L"Newest", fullpath );
    119                     console_print( full_info );
    120                 }
    121                 else if ( stA.st_mtime < stB.st_mtime )
    122                 {
    123                     swprintf(full_info, L"%8ls : %ls
    ", L"Newest", fullpath );
    124                     console_print( full_info );
    125                 }
    126                 else
    127                 {
    128                     //Same
    129                 }
    130             }
    131         }
    132     }
    133     _wclosedir(a);
    134     
    135 }
    136 
    137 void console_print(const wchar_t str[])
    138 {
    139     if ( ! g_bRedirect )
    140     {
    141         WriteConsoleW(
    142             GetStdHandle(STD_OUTPUT_HANDLE), str, wcslen(str)  , &written, NULL
    143         );
    144     }
    145     else
    146     {
    147         WriteFile(
    148             GetStdHandle(STD_OUTPUT_HANDLE), str, wcslen(str) * sizeof( str[0] ) , &written, NULL
    149         );
    150     }
    151 }
    152 
    153 void CheckConsoleRedirect(void)
    154 {
    155     if (!GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &written))
    156     {
    157         g_bRedirect = true;
    158         WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "xFFxFE", 2, &written, 0);
    159     }
    160 }
    161 
    162 void PATH_A_TO_B (
    163     const wchar_t source[], 
    164     const wchar_t a[], 
    165     const wchar_t b[], 
    166           wchar_t newstr[]
    167     )
    168 {
    169     int len_of_a = wcslen( a );
    170     wcscat( newstr, b );
    171     wcscat( newstr, source + len_of_a  );
    172 }
    173 
    174 bool FileExists(const wchar_t *wpath)
    175 {
    176     if (_waccess(wpath, 0) == -1) 
    177     {
    178         return FALSE;
    179     }
    180     else
    181     {
    182         return TRUE;
    183     }
    184 }
    185 
    186 bool FolderExists(const wchar_t *wpath)
    187 {
    188     return !!(_wopendir(wpath));
    189 }

    终端示例(部分内容用省略号表示):

    Console> Compare.exe D:Duplicateme H:me
    Extra : D:Duplicateme....
    Extra : D:Duplicateme....
    Newest : D:Duplicateme otes otebook.txt
    Older : D:Duplicateme免费获取有声读物.txt
  • 相关阅读:
    c++中的length,strlen;静态数据成员,静态局部变量
    c++中*的含义
    (1)引用的解释; (2)类的成员函数在类外实现的情况
    DbFunctions 作为 LINQ to Entities 查询的一部分使用时,此方法调用规范 CreateDateTime EDM 函数以创建新的 DateTime 对象。
    年视图,选择月份 ---bootstrap datepicker
    时间控件,页面刷新初始化时间控件只显示年月
    load加载层
    response 下载文件火狐浏览器文件名乱码问题
    Web Uploader
    layer是一款近年来备受青睐的web弹层组件
  • 原文地址:https://www.cnblogs.com/paktc/p/4990153.html
Copyright © 2011-2022 走看看