忍不了不忍了,做了个仓库盘检索系统
20年前构思过想要实现的这个东西,当时刻录盘太多了,需要找到某个东西很难。如今我把东西都往仓库硬盘里塞,逐渐硬盘数量也多起来。想找部旧电影来重温太麻烦,反复插拔了几个盘都没找到。
不能忍,用1小时把代码写了顺便把全部硬盘里的主要文件做了索引。
当年没有这个技术,现在用python+php+mysql实现起来相当简单的样子。
也不知道是技术变得平易近人还是我变厉害了..
20年前用 DOS命令 dir /s , tree /f > diskinfo.txt 然后再对一堆 txt 做文本检索。
现在用得主要命令是python 的 os.walk() 遍历整个盘。
代码简单概括如下(PHP部分略了,仅仅是查库)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 扫描硬盘分区构建文件索引存库
# Copyright 2020 <snmoney@gmail.com>
# win version
# 只有文件夹 与 大于 5M 的文件会被记录,太小的文件则直接忽略,
# 避免很多广告文件或者无关的小文件会增加数据库负担
# 像解压的漫画之类的可以忽略文件,只检索到目录就够了
import os
import mysql.connector
from mysql.connector import Error
from mysql.connector import errorcode
#借用网上别人的代码片段,字节转可读得文件大小
def sizeReadable(size, is_disk=False, precision=2):
formats = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
unit = 1000.0 if is_disk else 1024.0
if not(isinstance(size, float) or isinstance(size, int)):
raise TypeError('a float number or an integer number is required!')
if size < 0:
raise ValueError('number must be non-negative')
for i in formats:
size /= unit
if size < unit:
return str(round(size, precision)) + i
return str(round(size, precision)) + i
minFileSize = 5000000 #5M文件大小下限
inpDrv = input("扫描的盘符(不带,如 c 代表 C:\ ):")
inpDrv = inpDrv.upper()
inpDiskName = input("给磁盘一个名称:")
scanPath = inpDrv+":\\"
db_cfg = mysql.connector.connect(
host="localhost",
user="db_username",
passwd="db_password",
database="db_dbname"
)
db = db_cfg.cursor()
print((inpDiskName))
#写入一个磁盘名
sql = "INSERT INTO `disk_name`(`dname`) VALUES ('"+inpDiskName+"');"
try:
#db.execute(sql, vals)
db.execute(sql)
db_cfg.commit()
#获取 diskId
diskId = str(db.lastrowid)
except mysql.connector.Error as err:
print("mysql_err @diskname insert:", inpDiskName, err.msg)
diskId = 0
sql = "INSERT INTO `disk_tree`(`diskid`, `path`, `filename`, `filesize`) VALUES (%s, %s, %s, %s);"
fileTree = os.walk(scanPath)
matchCount = 0;
for i in fileTree:
#如果是空目录则记录目录名称
if(len(i[2])==0):
filename = "__DIR__" #特殊名称标记为目录
vals = (diskId, i[0], filename, '0')
db.execute(sql, vals)
else :
bigfilecount = 0 #如果目录下没有5M的文件,还是需要记录一个空目录
for f in i[2]:
try:
realPath = os.path.join(i[0], f)
fileSize = os.path.getsize(realPath)
if fileSize >= minFileSize : #小于5M不入库
#print(realPath, sizeReadable(fileSize)) #debug
matchCount += 1
bigfilecount += 1
vals = (diskId, i[0], f, sizeReadable(fileSize))
db.execute(sql, vals)
except OSError as err :
#部分文件可能村怀或特殊的文件名导致文件系统无法正确操作
#skip
print(str(err))
if bigfilecount == 0 :
filename = "__DIR__"
vals = (diskId, i[0], filename, '0')
db.execute(sql, vals)
db_cfg.commit() #每个文件夹提交一次
print("all match files:", matchCount)
