Re: FSIsAliasFile deprecated - typeOfFile is slow
Re: FSIsAliasFile deprecated - typeOfFile is slow
- Subject: Re: FSIsAliasFile deprecated - typeOfFile is slow
- From: Leonardo <email@hidden>
- Date: Tue, 01 Dec 2015 13:06:04 +0100
- Thread-topic: FSIsAliasFile deprecated - typeOfFile is slow
Thank you Gary. Almost got it.
Still a small question. The 8th byte of the buffer, in case of alias (file
or folder) returns -128 and not 128 as you said. Am I missing something?
- (BOOL)IsAlias
{
const char *cPath = [[NSFileManager defaultManager]
fileSystemRepresentationWithPath:self];
if(cPath == 0 || *cPath == _NUL) return NO;
const char *keyName = "com.apple.FinderInfo";
ssize_t bufferSize = getxattr(cPath, keyName, NULL, 0, 0, 0);
if(bufferSize < 32) return NO;
char *buffer = malloc(bufferSize);
if(buffer == nil) return NO;
getxattr(cPath, keyName, buffer, bufferSize, 0, 0);
BOOL isAlias = buffer[8] == -128;
free(buffer);
return isAlias;
}
Also, this method returns NO in case of SymLinks, as I expected.
And it's even 3 times faster than FSIsAliasFile().
That's fine.
I just hope that will work for the next 10 OS X releases...
Regards
-- Leonardo
> Da: "Gary L. Wade" <email@hidden>
> Data: Fri, 27 Nov 2015 16:48:43 -0800
> A: Leonardo <email@hidden>
> Cc: <email@hidden>
> Oggetto: Re: FSIsAliasFile deprecated - typeOfFile is slow
>
> Although I have experience with your performance hit, one solution I would
> probably try when it becomes important again for me would be to do this:
>
> 1. Using the BSD layer of APIs, see if the file (alias files are regular files
> from a statfs call, even folder aliases) has an extended attribute named
> "com.apple.FinderInfo". If it does not, it is not an alias file.
> 2. If the extended attribute does exist and is of length 32 bytes (or more
> although doubtful this would ever change), you might have an alias file. If
> less, just say no assuming corruption.
> 3. Get the bytes of the extended attribute and examine the byte at index 8
> (bytes[8]) to see if its high bit is set (bytes[8] | 0x80). If so, you have an
> alias; if not, you don't.
> 4. Add this logic in an appropriate category method (to keep this Cocoa).
>
> For reference, look up ATTR_CMN_FNDRINFO, xattr, Finder.h. Note this extended
> attribute has its integers in big-endian format. You might also look at the
> fileType parameter of the CoreServices FileInfo that maps the first 16 bytes,
> but that requires more checking.
> --
> Gary L. Wade (Sent from my iPhone)
> http://www.garywade.com/
>
>> On Nov 27, 2015, at 2:00 PM, Leonardo <email@hidden> wrote:
>>
>> Hi,
>> I actually detect whether a file is an alias this way:
>> I use a NSString category where self is the filePath.
>>
>> - (BOOL)IsAliasOld
>> {
>> FSRef sourceRef;
>>
>> OSErr err = [self GetFSRef:&sourceRef];
>> if(err) return NO;
>>
>> Boolean isFSDirectory, aliasFileFlag;
>>
>> err = FSIsAliasFile(&sourceRef, &aliasFileFlag, &isFSDirectory);
>> if(err) return NO;
>> else return aliasFileFlag;
>> }
>>
>> - (OSErr)GetFSRef:(FSRef*)sourceRef
>> {
>> const char *cSrcPath = [[NSFileManager defaultManager]
>> fileSystemRepresentationWithPath:self];
>> if(cSrcPath == 0 || *cSrcPath == _NUL) return -1;
>>
>> OSErr err = FSPathMakeRefWithOptions((UInt8*)cSrcPath,
>> kFSPathMakeRefDoNotFollowLeafSymlink, sourceRef, NULL);
>> return err;
>> }
>>
>>
>> Since FSIsAliasFile is deprecated (I compile for 10.9) I would now use
>>
>> - (BOOL)IsAliasNew
>> {
>> NSString *type = [[NSWorkspace sharedWorkspace] typeOfFile:self
>> error:nil];
>> return [type isEqualToString:@"com.apple.alias-file"];
>> }
>>
>> The problem is that the IsAliasNew method is 3.7 times slower than the
>> IsAliasOld method. Do you know a way to accomplish that with a faster
>> method?
>>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden