MxHanks' Blog

奔赴山海,保持热爱

0%

Python os.symlink() - 实现文件夹映射

Python os.symlink() - 实现文件夹映射

需求分析

最近因为使用了 obsidian 开始记笔记,发现这个软件实在是太好用了。之前写文章一直都是在 VSCode 上面,直接写在博客文件的 _post 目录下。但是最近我把所有的笔记都迁移到了 obsidian 的笔记库中,如果要更新博客的话就要把这个文件夹里面的所有文件都一次次复制到 _post 文件夹下,这样就很麻烦,于是就想通过镜像的方式来实现需求。

mklink 是 window s系统下创建符号链接和硬链接的命令工具,它是一个很好的解决文件系统问题的工具。使用它需要管理员权限。因为 powershell 不支持 mklink 命令,所以要在前面加cmd /c 表示用 cmd 来运行该命令,路径注意引号

C:\Users\?>mklink
创建符号链接。

MKLINK [[/D] | [/H] | [/J]] Link Target

        /D      创建目录符号链接。默认为文件
                符号链接。
        /H      创建硬链接而非符号链接。
        /J      创建目录联接。
        Link    指定新的符号链接名称。
        Target  指定新链接引用的路径
                (相对或绝对)

因为我想要忽略掉一些文件,但是又没有提供这个选项,所以我决定使用 python 来编写一个适合的程序。

概述

os.symlink() 方法用于创建符号链接(symbolic link)。

符号链接是一种特殊的文件类型,它包含对另一个文件或目录的引用,可以在文件系统中指向不同的位置。

语法

synlink() 方法语法格式如下:

os.symlink(src, dst)

参数

  • src – 要创建符号链接的目标文件或目录的路径。
  • dst – 符号链接的路径和名称。

实战

import os

SRC = "F:/Notes"
TGT = "F:/Projects/Blog-Pages/source/_posts"

# 忽略的目录 相对于 SRC 的相对路径
IGNORE_DIRS = (".obsidian", ".stfolder", "模板")
# 忽略的文件 相对于 SRC 的相对路径
IGNORE_FILES = (".stignore", "mxHanks变强之路.xmind")


# 第一步 检查要链接的路径是否已经存在
# 第二步 创造链接 并且捕捉异常
def create_symlink(src, tgt):
    try:
        os.symlink(src, tgt)
        print(f"创建软链接 {tgt} -> {src}")
    except Exception as e:
        print(f"创建失败 {tgt} -> {src}: {e}")


# 第一步 获得根目录的所有文件夹
# 第二部 将所有文件(夹)创建软链接
def screen(src, tgt, ign_dirs, ign_files):
    names = os.listdir(src)
    for name in names:
        path = os.path.realpath(os.path.join(src, name))
        # 路径是目录且不受忽略
        if os.path.isdir(path) and not name in ign_dirs:
            target_dir = os.path.realpath(os.path.join(tgt, name))
            if os.path.exists(target_dir):
                print(f"{target_dir} 目录已经存在,跳过建立")
            else:
                create_symlink(path, target_dir)
                print(f"{target_dir} 目录不存在,建立与 {path} 的链接")
        elif os.path.isfile(path) and not name in ign_files:
            target_file = os.path.realpath(os.path.join(tgt, name))
            if os.path.exists(target_file):
                print(f"{target_file} 文件已经存在,跳过建立")
            else:
                create_symlink(path, target_file)
                print(f"{target_file} 文件不存在,建立与 {path} 的链接")


screen(SRC, TGT, IGNORE_DIRS, IGNORE_FILES)

大功告成!