# File-Manager **Repository Path**: maxuxu2000/file-manager ## Basic Information - **Project Name**: File-Manager - **Description**: 文件分类器,通过方法一可以进行后缀判断,方法二通过监听键位分类。 - **Primary Language**: Python - **License**: OSL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2022-03-30 - **Last Updated**: 2023-07-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 1. python- 文件分类器 ## 1. 引言 由于文件太过杂乱,各种格式,各种类型的放在一起,一个个去拖动非常麻烦,于是想到了之前做过的一个项目,通过opencv2实现的视频分类,监听键位,通过对应键位来移动文件,而且我在其中也提到过其他文件分类的构想,现在正好有需求就完成这个项目吧。先阐述整体思路:1. 首先实现第一种分类方式:通过后缀来分类,也就是压缩包格式自动分为一类,视频格式分为一类,文本格式分为一类……。但是有一个问题通过后缀实现的分类仍然不是真正的分类,比如同样都是压缩包格式,但是压缩包也分为不同类型的,比如:学习类(高数,英语,计算机……),通过这种分类才能算作真正的分类,2. 所有第二种方式就是:通过键位绑定用户自定义的类型,让用户判断是哪一类的文件。 ## 2. 环境 ide * python3 * pycharm 库 * os : 文件操作 * shutil :文件移动 * keyboard:键盘监听 如果没有相关库,需要自己安装,打开cmd,执行以下代码: ```cmd pip install os pip install shutil pip install keyboard ``` ## 3. 公用方法 1. 扫描文件目录 ```python # 提升作用域,可以全局使用此变量 filepath = 'D:\\test2\\' # 扫描路径下的所有文件 listdir = os.listdir(filepath) ``` 2. 创建目录并移动方法 ```python # 创建目录并移动文件方法 def create_filepath(filename, old_filepath, new_filepath): # 判断目标文件夹是否存在,不存在则创建 if not os.path.exists(new_filepath): os.mkdir(new_filepath) # 判断有没有同名文件,没有则移动,有就pass if not os.path.exists(new_filepath + "\\" + filename): shutil.move(old_filepath, new_filepath) print(f"【{old_filepath}】已经被移动到【{new_filepath}】中") else: print(f"【{new_filepath}】目录中有同名文件【{filename}】,自判断是否删除") ``` >因为功能一两种方法都需要创建并移动文件所有单独创建一个公用方法,防止代码冗余。 > >此方法实现了根据传入的文件名,原始文件路径,目标文件路径,1.判断目标路径是否存在,不存在先创建 2. 判断目标路径是否已经有同名文件,如果有就跳过,3.判断要移动的是否是文件已经在调用方法之前判断过了,故此处不需要再判断。 ## 4. 自定义后缀分类 自定义后缀名进行分类,也就是让用户选择要对哪些后缀进行分类,比如我只想分类 zip,mp4,txt 其他类型的不想进行分类,就会只创建自定义的三种目录,然后扫描目标路径下所有符合的后缀 zip,mp4,txt ,符合要求的就会移动进去,其他文件不进行操作。 ```python # 1.思路一:自定义文件类型,按照自己定义的类型进行匹配;好处在于可以自己决定扫描和移动什么文件 def detect_file_type(file, file_type): if file.endswith(file_type): # print(file) # 传入创建目录 new_file_path = filepath + file_type old_file_path = filepath + file # 调用移动方法 create_filepath(old_file_path, new_file_path) ``` ```python def move_file1(): count_sum = 0 count_file = 0 count_dir = 0 for file in listdir: # if file.__contains__('.zip'): # print(file) # 判断后缀名是什么类型的,此处是直接判断好 filetype_list = ['exe', 'zip', 'txt'] if os.path.isfile(filepath + file): # 有可能文件没有后缀,考虑此情况 print(file) try: # 思路一:按照列表里定义好的进行分类 for filetype in filetype_list: detect_file_type(file, filetype) except: print(r"【{}】文件没有后缀类型,请自己判断".format(file)) # finally: # print(filetype) count_file += 1 else: count_dir += 1 count_sum += 1 print(r'总计扫描到的文件数【{}】和目录数【{}】,总计扫描到【{}】'.format(count_file, count_dir, count_sum)) ``` ## 5. 自动后缀分类 只想通过后缀分类所有文件,则自动创建所有包含的文件后缀的文件夹,判断所有的文件并移动 ```python # 2.思路二:自动扫描目录下的文件后缀,并创建相对应的文件夹 def auto_detect_file_type(file, file_type): new_file_path = filepath + file_type old_file_path = filepath + file create_filepath(old_file_path, new_file_path) ``` ```python def move_file2(): count_sum = 0 count_file = 0 count_dir = 0 for file in listdir: # 思路二:不判断直接根据后缀创建一个目录移动进去(更智能) if os.path.isfile(filepath + file): # 有可能文件没有后缀,考虑此情况 print(file) try: # 思路二:自动扫描后缀创建相对应的目录,然后进行分类 filetype = file.split('.')[1] auto_detect_file_type(file, filetype) except: print(r"【{}】文件没有后缀类型,请自己判断".format(file)) # finally: # print(filetype) count_file += 1 else: count_dir += 1 count_sum += 1 print(r'总计扫描到的文件数【{}】和目录数【{}】,总计扫描到【{}】'.format(count_file, count_dir, count_sum)) ``` ## 6. 自判断(键盘监听)分类 ### 6.1 全局变量 ```python # 提升作用域,可以全局使用此变量 filepath = 'D:\\test2\\' listdir = os.listdir(filepath) type_lists = ['软考', '学习视频', '学习资料', '游戏', '考研'] num_lists = ['a', '2', '3', '4', '5'] sum_lists = [] for tl, nl in zip(type_lists, num_lists): sum_lists.append('{{ ' + nl + ' ==>> ' + tl + ' }}') template_filepath = filepath + '同名文件自判断' ``` > 全局变量分别为 1.要扫描的目录;2.用户自编译的类别;3.为同名文件创建的目录 ### 6.2 创建文件并移动方法 ```python # 创建目录并移动文件方法 def create_filepath(filename, old_filepath, new_filepath): # 判断目标文件夹是否存在,不存在则创建 if not os.path.exists(new_filepath): os.mkdir(new_filepath) # print(r'创建文件夹:{}'.format(new_filepath)) else: # 判断有没有同名文件,没有则移动,有就pass if not os.path.exists(new_filepath + "\\" + filename): try: shutil.move(old_filepath, new_filepath) except: pass else: print(r"文件从【{}】移动到【{}】".format(old_filepath, new_filepath)) print("================确认操作,请按回车!!!否则无法判断下一个文件================") print('\t') else: if not os.path.exists(template_filepath): os.mkdir(template_filepath) try: shutil.move(old_filepath, template_filepath) except: pass else: print(f'同名文件自行判断') print("================确认操作,请按回车!!!否则无法判断下一个文件================") print('\t') ``` >因为移动操作会有报错风险,而且经过作者尝试,keyboard的热键监听在for循环判断目录下文件时,会有很大问题:移动第一个文件就一次,移动第二个文件就移动两次……。所以为解决此问题,用到了try-catch,同名文件移动到一个临时目录 《同名文件自行判断》中。如果有其他解决此问题的方法,欢迎讨论。 ### 6.3 调用创建文件方法 ```python # 执行移动操作 def move_file_to(filename, filetype): print(r'3移动了文件 {}'.format(filename)) new_file_path = filepath + filetype old_file_path = filepath + filename create_filepath(filename, old_file_path, new_file_path) ``` 此方法构造原文件路径和新文件路径,调用公用方法创建并移动文件 ### 6.4 键盘监听方法 ```python # 监听按键,设置热键 def listen_keyboard(filename): for filetype, num in zip(type_lists, num_lists): print(r'2传入的文件名:{}'.format(filename)) keyboard.add_hotkey(num, move_file_to, args=(filename, filetype)) keyboard.wait('enter') ``` 设置热键,监听用户自定义的文件类型,无论用户定义多少都会显示出来 ### 6.5 主方法 ```python def move_file_by_key(): for filename in listdir: if os.path.isfile(filepath + filename): # filetype = file.split('.')[1] print(r"1移动文件【{}】,并选择以下按键以便分类".format(filename)) print(sum_lists) listen_keyboard(filename) ``` 只负责判断文件,然后调用发放并传参 ## 7. 后缀分类-完整代码 ### 7.1 自定义后缀分类 ```python """ @Time : 2022/3/30 @Author : 16088 @File : 后缀分类 @Description : 按自定义后缀进行分类 """ import os import shutil """ 第一步,根据文件后缀移动到相对应格式目录下 """ # 提升作用域,可以全局使用此变量 filepath = 'D:\\test2\\' listdir = os.listdir(filepath) # 创建目录并移动文件方法 def create_filepath(filename, old_filepath, new_filepath): # 判断目标文件夹是否存在,不存在则创建 if not os.path.exists(new_filepath): os.mkdir(new_filepath) # 判断有没有同名文件,没有则移动,有就pass if not os.path.exists(new_filepath + "\\" + filename): shutil.move(old_filepath, new_filepath) print(f"【{old_filepath}】已经被移动到【{new_filepath}】中") else: print(f"【{new_filepath}】目录中有同名文件【{filename}】,自判断是否删除") # 1.思路一:自定义文件类型,按照自己定义的类型进行匹配;好处在于可以自己决定扫描和移动什么文件 def detect_file_type(file, file_type): if file.endswith(file_type): # 传入创建目录 new_file_path = filepath + file_type old_file_path = filepath + file # 调用移动方法 create_filepath(file, old_file_path, new_file_path) def move_file1(): count_sum = 0 count_file = 0 count_dir = 0 for file in listdir: # 判断后缀名是什么类型的,此处是直接判断好,思路二:不判断直接根据后缀创建一个目录移动进去(更智能) filetype_list = ['exe', 'zip', 'txt'] if os.path.isfile(filepath + file): # 有可能文件没有后缀,考虑此情况 try: # 思路一:按照列表里定义好的进行分类 for filetype in filetype_list: detect_file_type(file, filetype) except: print(r"【{}】文件没有后缀类型,请自己判断".format(file)) count_file += 1 else: count_dir += 1 count_sum += 1 print(r'总计扫描到的文件数【{}】和目录数【{}】,总计扫描到【{}】'.format(count_file, count_dir, count_sum)) if __name__ == '__main__': move_file1() ``` ### 7.2 自动后缀分类 ```python """ @Time : 2022/3/30 @Author : 16088 @File : 自动化后缀分类 @Description : 自动根据目标目录下的所有文件后缀进行分类 """ import os import shutil # 提升作用域,可以全局使用此变量 filepath = 'D:\\test2\\' listdir = os.listdir(filepath) # 创建目录并移动文件方法 def create_filepath(filename, old_filepath, new_filepath): # 判断目标文件夹是否存在,不存在则创建 if not os.path.exists(new_filepath): os.mkdir(new_filepath) # 判断有没有同名文件,没有则移动,有就pass if not os.path.exists(new_filepath + "\\" + filename): shutil.move(old_filepath, new_filepath) print(f"【{old_filepath}】已经被移动到【{new_filepath}】中") else: print(f"【{new_filepath}】目录中有同名文件【{filename}】,自判断是否删除") # 2.思路二:自动扫描目录下的文件后缀,并创建相对应的文件夹 def auto_detect_file_type(file, file_type): new_file_path = filepath + file_type old_file_path = filepath + file create_filepath(file, old_file_path, new_file_path) def move_file2(): count_sum = 0 count_file = 0 count_dir = 0 for file in listdir: # 思路二:不判断直接根据后缀创建一个目录移动进去(更智能) if os.path.isfile(filepath + file): # 有可能文件没有后缀,考虑此情况 # print(file) try: # 思路二:自动扫描后缀创建相对应的目录,然后进行分类 filetype = file.split('.')[1] auto_detect_file_type(file, filetype) except: print(r"【{}】文件没有后缀类型,请自己判断".format(file)) finally: print("进行下一个判断") count_file += 1 else: count_dir += 1 count_sum += 1 print(r'总计扫描到的文件数【{}】和目录数【{}】,总计扫描到【{}】'.format(count_file, count_dir, count_sum)) if __name__ == '__main__': move_file2() ``` ## 8. 自判断分类- 完整代码 ```python """ @Time : 2022/3/30 @Author : 16088 @File : 键位监听判断 @Description : 通过键位对应预先编译的几个类别进行判断 """ import os import shutil import keyboard """ 第一步,根据文件后缀移动到相对应格式目录下 """ # 提升作用域,可以全局使用此变量 filepath = 'D:\\test2\\' # filepath = 'D:\\Download\\Edge\\程序\\' listdir = os.listdir(filepath) # type_lists = ['编程开发', '便捷生活', '极客工具', '镜像', '实用工具', '虚拟机', '远控', '其它'] # num_lists = ['1', '2', '3', '4', '5', '6', '7', 'a'] type_lists = ['软考', '学习视频', '学习资料', '游戏', '考研'] num_lists = ['a', '2', '3', '4', '5'] sum_lists = [] for tl, nl in zip(type_lists, num_lists): sum_lists.append('{{ ' + nl + ' ==>> ' + tl + ' }}') template_filepath = filepath + '同名文件自判断' # 创建目录并移动文件方法 def create_filepath(filename, old_filepath, new_filepath): # 判断目标文件夹是否存在,不存在则创建 if not os.path.exists(new_filepath): os.mkdir(new_filepath) # print(r'创建文件夹:{}'.format(new_filepath)) else: # 判断有没有同名文件,没有则移动,有就pass if not os.path.exists(new_filepath + "\\" + filename): try: shutil.move(old_filepath, new_filepath) except: pass else: print(r"文件从【{}】移动到【{}】".format(old_filepath, new_filepath)) print("================确认操作,请按回车!!!否则无法判断下一个文件================") print('\t') else: if not os.path.exists(template_filepath): os.mkdir(template_filepath) try: shutil.move(old_filepath, template_filepath) except: pass else: print(f'同名文件自行判断') print("================确认操作,请按回车!!!否则无法判断下一个文件================") print('\t') """ 第二步:扫描文件名判断为何种类型 """ # 执行移动操作 def move_file_to(filename, filetype): new_file_path = filepath + filetype old_file_path = filepath + filename create_filepath(filename, old_file_path, new_file_path) # 监听按键,设置热键 def listen_keyboard(filename): for filetype, num in zip(type_lists, num_lists): keyboard.add_hotkey(num, move_file_to, args=(filename, filetype), suppress=False) keyboard.wait('enter') def move_file_by_key(): count = 1 for filename in listdir: if os.path.isfile(filepath + filename): # filetype = file.split('.')[1] print(f"👇👇👇判断第 #{count} 个文件【{filename}】,并选择以下按键以便分类👇👇👇") print("\t") print(sum_lists) listen_keyboard(filename) count += 1 if __name__ == '__main__': move_file_by_key() ``` ## 9. 总结 本来所有的方法都是写在一个文件中的,但是放在一起非常乱,而且需要注释掉另外两种方法,索性一份拆成三分(两个后缀分类方法和一个键盘监听方法),方便使用。此项目尚有很多的不足,当然本人能力有限,很多问题并没有完全解决,采用折中的方法实现基本功能,如果在测试和使用过程中遇到问题,可以直接与我联系,如果有其他想法或更好的思路,欢迎一起探讨。