Search code examples
objective-ccocoansstringmacos-carbon

NSString to FSRef conversion doesn't work


For my app I need to use the Carbon file manager API to get the size of a folder (NSEnumerator is slow, and using NSTask with a shell command is even worse). I've imported the Carbon framework, and I'm using this method to get the size of a folder:

http://www.cocoabuilder.com/archive/message/cocoa/2005/5/20/136503

It uses an FSRef as an argument, and my path string is currently an NSString. I tried using this to convert the NSString to an FSRef:

FSRef f;
        OSStatus os_status = FSPathMakeRef((const UInt8 *)[filePath fileSystemRepresentation], &f, NULL);

        if (os_status != noErr) {
            NSLog(@"fsref creation failed");
        }

And then I called the folder size method:

[self fastFolderSizeAtFSRef:f];

However when I try to build, I get this error regarding the above line:

error: incompatible type for argument one of 'fastFolderSizeAtFSRef:'

Any help would be appreciated. Thanks


Solution

  • The "fastFolderSizeAtFSRef" method takes an FSRef* (FSRef pointer). You're giving it an FSRef. It's a one character fix, luckily enough. You have:

    [self fastFolderSizeAtFSRef:f];
    

    Simply change that to:

    [self fastFolderSizeAtFSRef:&f];
    

    And you should be good to go. However, I was implementing this same method yesterday but was having trouble creating the FSRef itself. I eventually went with the following code:

    FSRef convertNSStringToFSRef(NSString * theString) {
        FSRef output;
        const char *filePathAsCString = [theString UTF8String];
        CFURLRef url = CFURLCreateWithBytes(kCFAllocatorDefault, 
                                            (const UInt8 *)filePathAsCString, 
                                            strlen(filePathAsCString),
                                            kCFStringEncodingUTF8,
                                            NULL);
        CFURLGetFSRef(url, &output);
        CFRelease(url);
        return output;
    }
    

    This has been working flawlessly for me.

    EDIT: I just open sourced the code that I'm using this in. It's these files:

    This file adds a method to NSFileManager that uses an FSRef to find the complete size of a directory. This file adds a method to NSString that will convert it to an FSRef.
    Everything happens on line 46 of this file.