Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
837 views
in Technique[技术] by (71.8m points)

macos - What replaces the now-deprecated Carbon.File.FSResolveAliasFile in Python on OSX?

In Python 2, I can use the following code to resolve either a MacOS alias or a symbolic link:

from Carbon import File
File.FSResolveAliasFile(alias_fp, True)[0].as_pathname()

where alias_fp is the path to the file I'm curious about, stored as a string (source).

However, the documentation cheerfully tells me that the whole Carbon family of modules is deprecated. What should I be using instead?

EDIT: I believe the code below is a step in the right direction for the PyObjC approach. It doesn't resolve aliases, but it seems to detect them.

from AppKit import NSWorkspace
def is_alias (path):
    uti, err = NSWorkspace.sharedWorkspace().typeOfFile_error_(
        os.path.realpath(path), None)
    if err:
        raise Exception(unicode(err))
    else:
        return "com.apple.alias-file" == uti

(source)

Unfortunately I'm not able to get @Milliways's solution working (knowing nothing about Cocoa) and stuff I find elsewhere on the internet looks far more complicated (perhaps it's handling all kinds of edge cases?).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The PyObjC bridge lets you access NSURL's bookmark handling, which is the modern (backwards compatible) replacement for aliases:

import os.path
from Foundation import *

def target_of_alias(path):
    url = NSURL.fileURLWithPath_(path)
    bookmarkData, error = NSURL.bookmarkDataWithContentsOfURL_error_(url, None)
    if bookmarkData is None:
        return None
    opts = NSURLBookmarkResolutionWithoutUI | NSURLBookmarkResolutionWithoutMounting
    resolved, stale, error = NSURL.URLByResolvingBookmarkData_options_relativeToURL_bookmarkDataIsStale_error_(bookmarkData, opts, None, None, None)
    return resolved.path()

def resolve_links_and_aliases(path):
    while True:
        alias_target = target_of_alias(path)
        if alias_target:
            path = alias_target
            continue
        if os.path.islink(path):
            path = os.path.realpath(path)
            continue
        return path

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...