【问题标题】:Converting a vRef and dirID (from a FSSpec) to a CFURL/NSURL将 vRef 和 dirID(从 FSSpec)转换为 CFURL/NSURL
【发布时间】:2014-07-31 20:02:31
【问题描述】:

我正在将我公司的一个应用程序迁移到 64 位环境,因此无法再访问 FSSpec 功能。

我们的文件格式中有一些数据结构,它们将旧 FSSpec 格式的 vRefNum 和 dirID 保存到文件中...过去我们能够使用 carbon 例程,从 FSSpec 到 FSRef,最后到 CFURL ,但 FSSpec 例程在 64 位中完全可用,甚至 FSRef 例程从 10.9 开始已被弃用。

我们在内部使用 CFURL/NSURL,但仍希望支持与这些旧文件格式之间的转换。有什么方法可以使用非弃用(或至少 64 位友好)例程在 vRefNum 和 dirID 之间往返 CFURL?

非常感谢。

【问题讨论】:

    标签: macos cocoa macos-carbon


    【解决方案1】:

    Apple 不支持此功能,但您可以使用 volfs 文件系统来执行此操作,这是 Carbon 内部所做的。请参阅 Apple 提供的以下文档:

    http://developer.apple.com/legacy/library/qa/qa2001/qa1113.html

    这是一个从卷 ID 和目录 ID 创建 CFURLRef 的函数:

    CFURLRef CreateURLFromVolumeIDandDirectoryID(dev_t volumeID, SInt32 directoryID)
    {
        CFStringRef thePath = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
            CFSTR("/.vol/%d/%d"), volumeID, (int) directoryID);
    
        CFURLRef theURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, thePath,
            kCFURLPOSIXPathStyle, false);
        CFRelease(thePath);
        return theURL;
    }
    

    要使用 volfs,您还需要将卷参考号转换为卷 ID。这是一种方法:

    dev_t ConvertVolumeRefNumtoVolumeID(FSVolumeRefNum refNum)
    {
        FSRef root;
        OSErr error = FSGetVolumeInfo(refNum, 0, NULL, kFSVolInfoNone, NULL, NULL, &root);
        if(error != noErr)
            return 0;
        UInt8 path[500];
        OSStatus status = FSRefMakePath(&root, path, 500);
        if(status != noErr)
            return 0;
        struct stat volStats;
        int err = stat((const char*)path, &volStats);
        if(err != 0)
            return 0;
    
        return volStats.st_dev;
    }
    

    根据链接的文档,应用程序不应该这样做,这可能会在任何未来版本的 OS X 中停止工作。但是你问...

    此外,当一个卷被卸载然后重新安装时,卷参考号不能保证保持不变,所以如果你将它们写入磁盘,你就会遇到另一个问题。

    【讨论】:

    • 现在,如果您还可以解释如何从这样的 volFS 路径获取常规路径,并且该路径也适用于识别符号链接的 volFS 路径,我将不胜感激。 (注意:open() 然后 fcntl(F_GETPATH) 不适用于符号链接的 volFS 路径)。
    【解决方案2】:

    我想说你们把它留了一点。 FSRef 于 2001 年出现。FSSpec 是前碳。我会说您需要一个 32 位帮助应用程序,它将 FSSpecs 转换为路径,然后通过分布式对象调用它。

    在您看到它们的任何地方替换 FSSpec。仅在需要时启动帮助应用程序,因此一段时间后用户将看不到它。

    【讨论】:

      猜你喜欢
      • 2016-08-29
      • 2014-12-18
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-28
      • 2012-02-10
      相关资源
      最近更新 更多