Board logo

标题: [文件操作] 仿dir命令部分功能,列出文件修改日期与路径列表 [打印本页]

作者: 523066680    时间: 2015-12-16 23:11     标题: 仿dir命令部分功能,列出文件修改日期与路径列表

本帖最后由 523066680 于 2015-12-17 00:09 编辑

代码比较臃肿,又有些多余的功能:支持重定向输出并且保留UNICODE字符
我是给那道题助攻的……  (然并卵!纯粹画蛇添足……
把递归去掉了,只列出参数指定目录的文件 以及 DIR FILE 的类型 、路径信息
重定向输出模式的间隔符为tab,utf16-le

有时间再添加参数选项,以及UNICODE开关吧

编译:g++ source.cpp
使用示例:list .\

输出格式像这样
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cwchar>
  4. #include <sys/stat.h>
  5. #include <dirent.h>
  6. #include <locale.h>
  7. #include <windows.h>
  8. #include <time.h>
  9. #define NAME_MAX 1024
  10. void func(wchar_t path[]);
  11. void time_to_date(time_t t, wchar_t * d_buf);
  12. static FILE * fp;
  13. DWORD written = 0;
  14. static bool g_bRedirect = false;
  15. void console_print(const wchar_t str[])
  16. {
  17.     if ( ! g_bRedirect )
  18.     {
  19.         WriteConsoleW(
  20.             GetStdHandle(STD_OUTPUT_HANDLE), str, wcslen(str)  , &written, NULL
  21.         );
  22.     }
  23.     else
  24.     {
  25.         WriteFile(
  26.             GetStdHandle(STD_OUTPUT_HANDLE), str, wcslen(str) * sizeof(str[0] ) , &written, NULL
  27.         );
  28.     }
  29. }
  30. void CheckConsoleRedirect(void)
  31. {
  32.     if (!GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &written))
  33.     {
  34.         g_bRedirect = true;
  35.         WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\xFF\xFE", 2, &written, 0);
  36.     }
  37. }
  38. int main(int argc, char *argv[] )
  39. {
  40.     setlocale( LC_ALL, ".936" );
  41.     wchar_t wspath[1024] = L"";
  42.     CheckConsoleRedirect();
  43.     if (argc > 1)
  44.     {
  45.         mbstowcs( wspath, argv[1], strlen(argv[1]) );
  46.         if ( wspath[wcslen(wspath)-1] != L'\\' )
  47.         {
  48.             wspath[wcslen(wspath)] = L'\\';
  49.             wspath[wcslen(wspath)+1] = L'\x00';
  50.         }
  51.         
  52.         _WDIR * a;
  53.         DIR * b;
  54.         if ( (a = _wopendir(wspath)) == NULL )
  55.         {
  56.             fprintf(stderr, "Argument is not correct!");
  57.         }
  58.         else
  59.         {
  60.             func( wspath );
  61.             fprintf(stderr, "All is done!");
  62.         }
  63.     }
  64.     else
  65.     {
  66.         fprintf(stderr, "No arguments!");
  67.     }
  68.    
  69.     return 0;
  70. }
  71. void func(wchar_t path[])
  72. {
  73.     _WDIR * a = _wopendir(path);
  74.     _wdirent * dp;
  75.     _WDIR * aa;
  76.     struct stat stbuf;
  77.     wchar_t fullpath[NAME_MAX] = L"";
  78.     while (dp = _wreaddir(a))
  79.     {
  80.         if (
  81.                wcscmp(dp->d_name, L".") == 0
  82.             || wcscmp(dp->d_name, L"..") == 0  
  83.         )
  84.         {
  85.             continue;
  86.         }
  87.         swprintf(fullpath, L"%ls%ls", path, dp->d_name);
  88.         wstat(fullpath, &stbuf);
  89.         wchar_t full_info[NAME_MAX + 32] = L"";
  90.         wchar_t mt_date[11] = L"";
  91.         time_to_date(stbuf.st_mtime, mt_date);
  92.         
  93.         if ( (stbuf.st_mode & S_IFMT) == S_IFDIR )
  94.         {
  95.             swprintf(full_info, L"%ls\t<DIR>\t%ls\r\n", mt_date, fullpath );
  96.         }
  97.         else
  98.         {   
  99.             swprintf(full_info, L"%ls\t<FILE>\t%ls\r\n", mt_date, fullpath );
  100.         }
  101.         console_print( full_info );
  102.     }
  103.     _wclosedir(a);
  104. }
  105. void time_to_date(time_t t, wchar_t * d_buf)
  106. {
  107.     struct tm *timeinfo;
  108.     timeinfo = localtime( &t );
  109.     swprintf(
  110.         d_buf,
  111.         L"%04d-%02d-%02d",
  112.         timeinfo->tm_year + 1900,
  113.         timeinfo->tm_mon + 1,
  114.         timeinfo->tm_mday
  115.     );
  116. }
复制代码

作者: 523066680    时间: 2015-12-16 23:20

本帖最后由 523066680 于 2015-12-17 00:02 编辑

论坛的代码框啥时候升级?
phpbb的代码框我已经设置得很6了。
inline模式,滚动条模式、可以展开/收缩的模式

不然代码长了滚屏看帖子很烦的,除非用户自己上传文件

http://www.open-gl.org/viewtopic.php?f=63&t=464
http://www.open-gl.org/viewtopic.php?f=63&t=466

修改方法应该类似,改css,添加tag标签,比如[ codex ]

(最近广告有点重 ……
作者: 523066680    时间: 2015-12-16 23:48     标题: 递归版

本帖最后由 523066680 于 2015-12-17 00:25 编辑

递归版,这个代码改一下就可以列出带文件大小的文件列表
但是递归还是要注意硬链接,我已经知道相关函数,有时间会继续改进

--- TreeV3_YYYYMMDD.cpp 2015-12-17 00:07:48.186728000 +0800
+++ TreeV3_YMD_R.cpp    2015-12-16 23:46:07.824351600 +0800
@@ -108,6 +108,8 @@
         if ( (stbuf.st_mode & S_IFMT) == S_IFDIR )
         {
             swprintf(full_info, L"%ls\t<DIR>\t%ls\r\n", mt_date, fullpath );
+            wcscat(fullpath, L"\\");
+            func(fullpath);
         }
         else
         {   


补充,刚才测试递归整个D盘会崩溃退出
原因:
遇到一个这样的文件:
修改日期为:
1953‎年‎11‎月‎26‎日,‏‎14:03:06
作者: codegay    时间: 2015-12-17 03:41

能把利用everything 的API实现搜索功能吗?
作者: CrLf    时间: 2015-12-17 07:40

对 HASH 稍加修改,编译了一个 w 版:http://www.bathome.net/s/tool/?key=HASHw
现在也可支持 wchar_t 了,不过代价是 PCRE 正则不能用...要用也可以,不过还要来回转 UTF-8 实在太麻烦
  1. hashw /format:"%%s\t%%s\n",t:"%%Y%%m%%d",name /a:: /d
复制代码
本人专注于造轮子 100 年,造的轮子可环绕地球两周
作者: CrLf    时间: 2015-12-17 07:44

本帖最后由 CrLf 于 2015-12-17 07:45 编辑

回复 4# codegay


hash 可以这样间接实现:
  1. @echo off
  2. es *.txt | hash /t:"%%Y%%m%%d" /f con
复制代码
  1. @echo off
  2. es *.txt >list.$
  3. hash /t:"%%Y%%m%%d" /f list.$
复制代码

作者: 523066680    时间: 2015-12-17 10:00

本帖最后由 523066680 于 2015-12-17 10:37 编辑

回复 4# codegay
回复 6# CrLf

    Everything 对目录系统列表的更新速度比一般遍历速度快的原因:
https://www.zhihu.com/question/25280685

作者:沈东渐
链接:https://www.zhihu.com/question/25280685/answer/30828004
来源:知乎

USN日志的工作方式,相对来说很简单,所以非常的高效。它开始的时候是一个空文件,包括NTFS每个卷的信息。每当NTFS卷有改变的时候,所改变的信息会马上被添加到这个文件里。这其中,每条修改的记录都使用特定符号来标识为日志形式,也就是USN日志。每条日志,记录了包括文件名、文件信息做出的改变,日志里包括发生了什么变化(添加、删除或其他操作)。


暂时不知道怎么用,MSDN好像有介绍,纯英文……
作者: codegay    时间: 2015-12-17 11:13

回复 7# 523066680


    everything官方提供了有SDK 你看看有没有用?
https://www.voidtools.com/support/everything/sdk/
作者: aa77dd@163.com    时间: 2015-12-17 11:33

回复 7# 523066680

文件系统的 棱镜计划

索引服务 也对 文件系统 实时监控, 让系统卡顿的一罪魁
作者: 523066680    时间: 2015-12-17 11:34

本帖最后由 523066680 于 2015-12-17 11:36 编辑

回复 8# codegay

    哦,他这个API还提供了示例,看上去很方便使用

我主要是说不知道Everything实际对USN的读取操作是怎么做的

8楼是9楼的马甲吗
作者: 523066680    时间: 2015-12-17 11:51

本帖最后由 523066680 于 2015-12-17 12:10 编辑

回复 8# codegay

看了一下命令行版本  (还是命令方便哇

Desktop>es --help
-r Search the database using a basic POSIX regular expression.
-i Does a case sensitive search.
-w Does a whole word search.
-p Does a full path search.
-h --help Display this help.
-n <num> Limit the amount of results shown to <num>.
-s Sort by full path.

运行前需要按这个帖子操作一下,否则提示 Everything IPC service not running.
http://www.voidtools.com/forum/viewtopic.php?f=5&t=1745

下载everything.exe便携版,以及 es.zip
然后按以下步骤操作即可使用es命令
install the service (this will automatically request admin privileges, you can skip this if the service is already installed):
    Everything.exe -install-service

Run the Everything client:
    Everything.exe

Finally run es:
    es.exe
作者: 523066680    时间: 2015-12-17 12:02

本帖最后由 523066680 于 2015-12-17 12:13 编辑

我都忘了批处理可以直接对完整路径进行  %~si %~ti操作 不过在枚举后逐个提取日期、大小信息,
效率自然是不一样的。轮子还是可以写
作者: aa77dd@163.com    时间: 2015-12-17 13:24

回复 10# 523066680

从 空格 空行 和 标点符号 的使用习惯, 你应该判断出 8 楼和我木有马甲关系
作者: 523066680    时间: 2015-12-17 13:50

回复 13# aa77dd@163.com


    我记错人了哈哈哈,我以为是依山居 因为依山居在python区发了好多帖子
根据他们的签名
作者: CrLf    时间: 2015-12-17 17:09

回复 10# 523066680


    读usn,删usn,监视usn,无论哪一步都需要管理员权限
     另外,你个二货,版主是可以看 ip 的
作者: 523066680    时间: 2015-12-17 18:01

回复 15# CrLf


    哦,没事不去看IP
作者: CrLf    时间: 2015-12-17 18:21

回复 16# 523066680


    最不爽的就是:即使看了 IP,也不知道某些 ID 是不是 Batcher 马甲




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2