Plain Notes技术札记
← 全部笔记
文件管理

整理文件之前,先生成一份清单

文件整理脚本最容易写的部分是移动和删除,最重要的部分却是确认对象。不同目录中同名的文件可能完全不同,文件名不同的内容也可能相同。

与其立即操作,不如先生成一份可检查的清单。它既是预览,也是操作后的对照依据。

第一步只读,不移动

先记录相对路径、文件大小和内容摘要。路径用于定位,大小可快速排除大部分不相同的文件,摘要则适合进一步比较。

from pathlib import Path
import hashlib
import csv

def digest(path):
    result = hashlib.sha256()
    with path.open("rb") as stream:
        for block in iter(lambda: stream.read(1024 * 1024), b""):
            result.update(block)
    return result.hexdigest()

root = Path("./documents").resolve()
with open("file-inventory.csv", "w", newline="",
          encoding="utf-8") as output:
    writer = csv.writer(output)
    writer.writerow(["path", "bytes", "sha256"])
    for path in sorted(root.rglob("*")):
        if path.is_file() and not path.is_symlink():
            writer.writerow([str(path.relative_to(root)),
                             path.stat().st_size, digest(path)])

示例将输出写在被扫描目录之外,并跳过符号链接。对于正在持续写入的目录,应先停止写入或使用快照,否则扫描中的大小和内容可能发生变化。

重名冲突要先决定规则

不要让后出现的文件直接覆盖先出现的文件。更可靠的选择,是遇到冲突便停止,或者在清单中列出目标路径,由人检查后再执行。

“相同内容”也不必然等于“应该删除”:两个项目可能各自需要同一个资源。清理前仍应确认引用关系和保留位置。

使用临时归档代替立即删除

确认要清理的文件,可以先移入单独的待清理目录,并记录原始位置。保留一段时间,在相关程序仍能正常运行后,再决定是否永久删除。

同一磁盘上的另一个文件夹方便撤销,但不是独立备份。重要文件还应有另一份可验证的副本。

操作后按清单核对

把预览、执行、核对拆开,通常比编写一个“一键整理”按钮更值得。