gpt4 book ai didi

python - 如何从 python 读取、更改和写入 macOS 文件别名

转载 作者:太空宇宙 更新时间:2023-11-04 04:48:49 25 4
gpt4 key购买 nike

有什么方法可以读取 macOS 文件别名、修改其内容(特别是目标文件路径)并将修改后的别名写回吗?

例如,如果我有以下目录结构:

./one/file.txt
./two/file.txt
./file_alias

其中 file_alias 解析为 ./one/file.txt。我希望能够以编程方式在 Python 中读取 ./file_alias,确定其路径,将“一”更改为“二”,然后写出修改后的别名,覆盖 ./文件别名。完成后,file_alias 将解析为 ./two/file.txt

通过搜索,我找到了一个相关问题的答案,表明它无法完成(@Milliway 对 [1] 的回答),一个没有实质性文档的 Carbon 模块,并声明其功能已被删除 [2 ],一个部分弃用的 macostools 模块,它依赖于 Carbon [3],一个等效的,未回答的问题(除了使用 PyObjC 的暂定建议)[4],以及最近更新的 mac_alias 包 [5],但还没有找到一种方法来根据其中任何一项完成任务。

mac_alias 包起初看起来很有趣,但我发现没有办法从现有的别名文件中导入构建内存中 Alias 对象所需的字节(使用二进制读取的字节)别名文件会产生错误),即使我可以构建内存中的 Alias 记录并对其进行修改,也无法将其写出到磁盘。

我想要它的机器正在运行 10.12.x (Sierra),我正在使用内置的 python 2.7.10。我发现我实际上可以导入 Carbon 和 macostools,并且怀疑 Carbon.File 可能会提供我需要的东西,但我找不到它的任何文档。我可以升级到 High Sierra 和/或安装和使用 Python 3.x,但这些在现阶段似乎没有帮助或相关。

我意识到别名还包含一个 inode,经过这样的更改后它会过时,但值得庆幸的是,部分原因是我提交的错误以及我在 Apple 时的一些坚持,别名解析了路径首先,只有在路径解析失败时才回退到 inode,如果路径解析成功(并且 inode 已更改)则更新 inode。

感谢任何帮助、建议和指点。

[1] How to handle OSX Aliases in Python with os.walk()?
[2] https://docs.python.org/2/library/carbon.html
[3] https://docs.python.org/2/library/macostools.html
[4] change an alias target python
[5] https://pypi.python.org/pypi/mac_alias

最佳答案

使用 PyObjC 解决了它,尽管几乎没有 PyObjC 的文档。您必须小心地将 NSURL 的 ObjectiveC 接口(interface)转换为 PyObjC 调用,使用在 this site 上找到的“PyObjC 简介”中描述的技术。同时引用描述的 NSURL 接口(interface) here .

@MagerValp 对 this question 的回复中的代码帮助弄清楚如何获得别名的目标。我必须弄清楚如何使用修改后的目标创建新别名。

下面是一个测试程序,其中包含并练习了所有需要的功能。它的设置和使用记录在代码中的注释中。

我是一个坏人,没有做文档字符串或输入和返回值的描述,但我保持所有函数简短且功能单一,希望我已经足够清楚地命名所有变量和函数,以便它们不需要。公认的 CamelCaps 和 underscore_separated 变量和函数名称的奇怪组合。我通常将 CamelCaps 用于全局常量,将下划线分隔的名称用于函数和变量,但在这种情况下,我想保留 PyObjC 调用中引用的变量和数据类型,它们使用 camelCaps,保持不变,因此是奇怪的组合。

请注意,Mac Finder 会缓存一些有关别名的信息。因此,如果您在运行此程序后立即对 file_alias 执行 Get Info 或 resolve,它看起来好像没有工作,即使它确实工作了。您必须将 one 文件夹拖到废纸篓清空废纸篓,然后 Get Info 或解析 file_alias 才会显示它现在确实指向 ./two/file.txt。 (咕噜咕噜。)幸运的是,这不会影响我对这些技术的使用,也不会影响大多数人的使用,我怀疑。该程序的重​​点通常是用一个固定的别名替换一个损坏的别名,基于这样一个事实,即一些单一的、简单的东西发生了变化,比如这个例子中的文件夹名称,或者我的真实应用程序中的卷名。

最后是代码:

#!/usr/bin/env python

# fix_alias.py
# A test program to exercise functionality for retargeting a macOS file alias (bookmark).
# Author: Larry Yaeger, 20 Feb 2018
#
# Create a file and directory hierarchy like the following:
#
# one
# file.txt
# two
# file.txt
# file_alias
#
# where one and two are folders, the file.txt files are any files really, and
# file_alias is a Mac file alias that points to ./one/file.txt. Then run this program
# in the same folder as one, two, and file_alias. It will replace file_alias with
# an alias that points to ./two/file.txt.
#
# Note that file_alias is NOT a symbolic link, even though the Mac Finder sometimes
# pretends symbolic links are aliases; they are not.

import os
import string

from Foundation import *


OldFolder = 'one'
NewFolder = 'two'
AliasPath = 'file_alias'


def get_bookmarkData(alias_path):
alias_url = NSURL.fileURLWithPath_(alias_path)
bookmarkData, error = NSURL.bookmarkDataWithContentsOfURL_error_(alias_url, None)
return bookmarkData


def get_target_of_bookmarkData(bookmarkData):
if bookmarkData is None:
return None
options = NSURLBookmarkResolutionWithoutUI | NSURLBookmarkResolutionWithoutMounting
resolved_url, stale, error = \
NSURL.URLByResolvingBookmarkData_options_relativeToURL_bookmarkDataIsStale_error_(
bookmarkData, options, None, None, None)
return resolved_url.path()


def create_bookmarkData(new_path):
new_url = NSURL.fileURLWithPath_(new_path)
options = NSURLBookmarkCreationSuitableForBookmarkFile
new_bookmarkData, error = \
new_url.bookmarkDataWithOptions_includingResourceValuesForKeys_relativeToURL_error_(
options, None, None, None)
return new_bookmarkData


def create_alias(bookmarkData, alias_path):
alias_url = NSURL.fileURLWithPath_(alias_path)
options = NSURLBookmarkCreationSuitableForBookmarkFile
success, error = NSURL.writeBookmarkData_toURL_options_error_(bookmarkData, alias_url, options, None)
return success


def main():
old_bookmarkData = get_bookmarkData(AliasPath)
old_path = get_target_of_bookmarkData(old_bookmarkData)
print old_path
new_path = string.replace(old_path, OldFolder, NewFolder, 1)
new_bookmarkData = create_bookmarkData(new_path)
new_path = get_target_of_bookmarkData(new_bookmarkData)
print new_path
os.remove(AliasPath)
create_alias(new_bookmarkData, AliasPath)


main()

关于python - 如何从 python 读取、更改和写入 macOS 文件别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48862093/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com