将vRef和dirID(从FSSpec)转换为CFURL / NSURL

时间:2014-07-31 20:02:32

标签: macos cocoa macos-carbon

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

我们的文件格式中有一些数据结构将vRefNum和dirID从旧的FSSpec格式保存到文件中...过去我们能够使用碳惯例,从FSSpec到FSRef,最后到CFURL ,但FSSpec例程在64位中全部可用,甚至FSRef例程也不推荐使用10.9。

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

非常感谢。

2 个答案:

答案 0 :(得分:0)

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中工作。但是你问...

此外,在卸载卷然后重新安装卷时,不保证卷引用号保持不变,因此如果将它们写入磁盘,则会出现另一个问题。

答案 1 :(得分:-2)

我会说你们离开的时间有点长。 FSRef于2001年在那里.FSSpec是前碳。我要说你需要一个32位帮助应用程序,它将FSSpec转换为路径,然后通过分布式对象调用它。

将FSSpec替换为您看到的任何地方。只在需要时启动帮助应用程序,所以一段时间后用户将不再看到它。