Python小技巧|如何在win系统下快速查找文件

举报
悦来客栈的老板 发表于 2020/12/29 00:34:59 2020/12/29
【摘要】 在工作的时候有时需要去处理一些文件,如果不在一个文件夹里面会去遍历整个盘符(如F盘),这个时候手动查找和搜索显得非常慢,单个还好,如果多个,就不得不写程序来处理了。 据我所知,Python有两个函数可以遍历文件夹(包括子文件夹),os模块的walk函数,以及glob模块的glob函数,其中os.walk函数,查看help文档有示例代码: import osfrom ...

在工作的时候有时需要去处理一些文件,如果不在一个文件夹里面会去遍历整个盘符(如F盘),这个时候手动查找和搜索显得非常慢,单个还好,如果多个,就不得不写程序来处理了。

据我所知,Python有两个函数可以遍历文件夹(包括子文件夹),os模块的walk函数,以及glob模块的glob函数,其中os.walk函数,查看help文档有示例代码:


   
  1. import os
  2. from os.path import join, getsize
  3. for root, dirs, files in os.walk('python/Lib/email'):
  4. print(root, "consumes", end="")
  5. print(sum([getsize(join(root, name)) for name in files]), end="")
  6. print("bytes in", len(files), "non-directory files")
  7. if 'CVS' in dirs:
  8. dirs.remove('CVS') # don't visit CVS directories

可以直接拿来用,而glob.glob函数虽然没提供示例,但help文档也很清晰:


   
  1. glob(pathname, *, recursive=False)
  2. Return a list of paths matching a pathname pattern.
  3. The pattern may contain simple shell-style wildcards a la
  4. fnmatch. However, unlike fnmatch, filenames starting with a
  5. dot are special cases that are not matched by '*' and '?'
  6. patterns.
  7. If recursive is true, the pattern '**' will match any files and
  8. zero or more directories and subdirectories.

不难理解,第二个参数为**,且第三个参数为recursive=True时,即可以遍历指定的路径(包含子文件夹):

glob(pathname, **, recursive=True)

  

但是很遗憾的是,这两个函数在遍历文件和子文件夹比较多的文件夹时,会显非常慢,如果你使用的是 win系统,则可以尝试另外的方式。

很多朋友应该听过 Everything 这个查找神器,下载地址:

https://www.voidtools.com/zh-cn/downloads/

  

它在win系统下搜索文件可以说非常的快速,更多介绍请看这里:

https://www.voidtools.com/zh-cn/faq/

  

那怎么写程序来调用呢?它提供了SDK:


   
  1. http://www.voidtools.com/support/everything/sdk/

函数非常的多,也给了Python的调用示例:


   
  1. import ctypes
  2. import datetime
  3. import struct
  4. #defines
  5. EVERYTHING_REQUEST_FILE_NAME = 0x00000001
  6. EVERYTHING_REQUEST_PATH = 0x00000002
  7. EVERYTHING_REQUEST_FULL_PATH_AND_FILE_NAME = 0x00000004
  8. EVERYTHING_REQUEST_EXTENSION = 0x00000008
  9. EVERYTHING_REQUEST_SIZE = 0x00000010
  10. EVERYTHING_REQUEST_DATE_CREATED = 0x00000020
  11. EVERYTHING_REQUEST_DATE_MODIFIED = 0x00000040
  12. EVERYTHING_REQUEST_DATE_ACCESSED = 0x00000080
  13. EVERYTHING_REQUEST_ATTRIBUTES = 0x00000100
  14. EVERYTHING_REQUEST_FILE_LIST_FILE_NAME = 0x00000200
  15. EVERYTHING_REQUEST_RUN_COUNT = 0x00000400
  16. EVERYTHING_REQUEST_DATE_RUN = 0x00000800
  17. EVERYTHING_REQUEST_DATE_RECENTLY_CHANGED = 0x00001000
  18. EVERYTHING_REQUEST_HIGHLIGHTED_FILE_NAME = 0x00002000
  19. EVERYTHING_REQUEST_HIGHLIGHTED_PATH = 0x00004000
  20. EVERYTHING_REQUEST_HIGHLIGHTED_FULL_PATH_AND_FILE_NAME = 0x00008000
  21. #dll imports
  22. everything_dll = ctypes.WinDLL ("C:\\EverythingSDK\\DLL\\Everything32.dll")
  23. everything_dll.Everything_GetResultDateModified.argtypes = [ctypes.c_int,ctypes.POINTER(ctypes.c_ulonglong)]
  24. everything_dll.Everything_GetResultSize.argtypes = [ctypes.c_int,ctypes.POINTER(ctypes.c_ulonglong)]
  25. #setup search
  26. everything_dll.Everything_SetSearchW("test.py")
  27. everything_dll.Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME | EVERYTHING_REQUEST_PATH | EVERYTHING_REQUEST_SIZE | EVERYTHING_REQUEST_DATE_MODIFIED)
  28. #execute the query
  29. everything_dll.Everything_QueryW(1)
  30. #get the number of results
  31. num_results = everything_dll.Everything_GetNumResults()
  32. #show the number of results
  33. print("Result Count: {}".format(num_results))
  34. #convert a windows FILETIME to a python datetime
  35. #https://stackoverflow.com/questions/39481221/convert-datetime-back-to-windows-64-bit-filetime
  36. WINDOWS_TICKS = int(1/10**-7) # 10,000,000 (100 nanoseconds or .1 microseconds)
  37. WINDOWS_EPOCH = datetime.datetime.strptime('1601-01-01 00:00:00',
  38. '%Y-%m-%d %H:%M:%S')
  39. POSIX_EPOCH = datetime.datetime.strptime('1970-01-01 00:00:00',
  40. '%Y-%m-%d %H:%M:%S')
  41. EPOCH_DIFF = (POSIX_EPOCH - WINDOWS_EPOCH).total_seconds() # 11644473600.0
  42. WINDOWS_TICKS_TO_POSIX_EPOCH = EPOCH_DIFF * WINDOWS_TICKS # 116444736000000000.0
  43. def get_time(filetime):
  44. """Convert windows filetime winticks to python datetime.datetime."""
  45. winticks = struct.unpack('<Q', filetime)[0]
  46. microsecs = (winticks - WINDOWS_TICKS_TO_POSIX_EPOCH) / WINDOWS_TICKS
  47. return datetime.datetime.fromtimestamp(microsecs)
  48. #create buffers
  49. filename = ctypes.create_unicode_buffer(260)
  50. date_modified_filetime = ctypes.c_ulonglong(1)
  51. file_size = ctypes.c_ulonglong(1)
  52. #show results
  53. for i in range(num_results):
  54. everything_dll.Everything_GetResultFullPathNameW(i,filename,260)
  55. everything_dll.Everything_GetResultDateModified(i,date_modified_filetime)
  56. everything_dll.Everything_GetResultSize(i,file_size)
  57. print("Filename: {}\nDate Modified: {}\nSize: {} bytes\n".format(ctypes.wstring_at(filename),get_time(date_modified_filetime),file_size.value))

显得比较难以理解,我自己照着其他的示例写了个简单易理解的,代码如下:


   
  1. from ctypes import windll,byref,create_unicode_buffer
  2. def search_files(file):
  3. Search = windll.LoadLibrary("everything64.dll")
  4. strBuff = create_unicode_buffer(255)
  5. Search.Everything_SetSearchW(file)
  6. Search.Everything_QueryW(True)
  7. Results = Search.Everything_GetNumResults()
  8. for index in range(Results):
  9. Search.Everything_GetResultFullPathNameW(index,byref(strBuff),len(strBuff))
  10. yield strBuff.value
  11. del Search
  12. del strBuff
  13. if __name__=='__main__':
  14.     for file in search_files('*.py'):
  15. print (file) 

在调用它的SDK时,网站上也很贴心的给了我们一些注意事项:

简而言之就是在调用的时候,一定要打开 Everything 这个软件。更多的功能请自己去发现吧^_^

文章来源: blog.csdn.net,作者:悦来客栈的老板,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq523176585/article/details/109508005

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。