来自FSCopyURLForVolume的完整网址

时间:2012-03-10 00:39:23

标签: objective-c cocoa core-services

我在使用FSCopyURLForVolume获取文件的完整网址时遇到了问题。我正在使用此问题的代码Determine AFP share from a file URL,但它没有给我完整的网址。例如:

使用以下路径:/Volume/server/html/index.html

我回来的只是基座的网址:nfs://real_server_name/vol

叶目录和文件名保持关闭,文件信息中提供了完整路径,因此必须有一种获取此信息的方法。

修改

经过一些挖掘后,似乎我想使用kFSCatInfoParentDirIDkFSCatInfoNodeID来获取父节点和节点(文件)ID,但我不确定如何将其变为有用的东西。< / p>

2 个答案:

答案 0 :(得分:2)

因为在Mac OS X 10.8中不推荐使用FSPathMakeRef,FSGetCatalogInfo和FSCopyURLForVolume,所以我在Mac OS X安装卷上实现了获取UNC网络路径的代码现代化。

    NSError *error=nil; //Error 
    NSURL *volumePath=nil; //result of UNC network mounting path 

    NSString* testPath =@"/Volumes/SCAMBIO/testreport.exe"; //File path to test 

    NSURL *testUrl = [NSURL fileURLWithPath:testPath]; //Create a NSURL from file path
    NSString* mountPath = [testPath stringByDeletingLastPathComponent]; //Get only mounted volume part i.e. /Volumes/SCAMBIO
    NSString* pathComponents = [testPath substringFromIndex:[mountPath length]]; //Get the rest of the path starting after the mounted path i.e. /testereport.exe
   [testUrl getResourceValue:&volumePath forKey:NSURLVolumeURLForRemountingKey error:&error]; //Get real UNC network mounted path i.e. smb://....

    NSLog(@"Path: %@%@", volumePath,pathComponents); //Write result to debug console

结果在我的情况下, 路径: smb://FRANCESCO@192.168.69.44/SCAMBIO/testreport.exe

您需要指定网络映射卷。

答案 1 :(得分:0)

Apple Dev Forums建议解决这个问题,这是我提出的最终功能:

- (NSURL *)volumeMountPathFromPath:(NSString *)path{
    NSString *mountPath = nil;
    NSString *testPath = [path copy];
    while(![testPath isEqualToString:@"/"]){
        NSURL *testUrl = [NSURL fileURLWithPath:testPath];
        NSNumber *isVolumeKey;
        [testUrl getResourceValue:&isVolumeKey forKey:NSURLIsVolumeKey error:nil];
        if([isVolumeKey boolValue]){
            mountPath = testPath;
            break;
        }        
        testPath = [testPath stringByDeletingLastPathComponent];
    }

    if(mountPath == nil){
        return nil;
    }

    NSString *pathCompointents = [path substringFromIndex:[mountPath length]];

    FSRef pathRef;
    FSPathMakeRef((UInt8*)[path fileSystemRepresentation], &pathRef, NULL);
    FSCatalogInfo catalogInfo;
    OSErr osErr = FSGetCatalogInfo(&pathRef, kFSCatInfoVolume|kFSCatInfoParentDirID,
                                   &catalogInfo, NULL, NULL, NULL);
    FSVolumeRefNum volumeRefNum = 0;
    if(osErr == noErr){
        volumeRefNum = catalogInfo.volume;
    }

    CFURLRef serverLocation;
    OSStatus result = FSCopyURLForVolume(volumeRefNum, &serverLocation);
    if(result == noErr){
        NSString *fullUrl = [NSString stringWithFormat:@"%@%@", 
                             CFURLGetString(serverLocation), pathCompointents];        
        return [NSURL URLWithString:fullUrl];
    }else{
        NSLog(@"Error getting the mount path: %i", result);
    }
    return nil;
}