Can't get file type code using [fileAttr valueForKey:NSFileHFSTypeCode]

  • I am trying to build a list of files found on my hard disk that pass a
    certain filter (predicate). Mostly my code works, but I want to get the
    modification date and the type code of each file. I am getting the date OK,
    but not the type code, which should be ³TEXT² for text files and might be
    ³WBBN² for a Microsoft Word document. Here is part of the code of my
    controller:

    NSFileManager *defMgr = [NSFileManager defaultManager];
    NSDirectoryEnumerator *dirEnum =
        [defMgr enumeratorAtPath:placeToSearch];
    while (file = [dirEnum nextObject]) {
        fileAttr = [dirEnum fileAttributes];
        hfsFileType = [fileAttr valueForKey:NSFileHFSTypeCode];
        modDate = [fileAttr valueForKey:NSFileModificationDate];

    Can anyone tell me what is wrong?

    And by the way, how do I convert hfsFileType into a string? (Maybe I can
    figure that one out myself from the documentation.)

    Lynn
  • On May 21, 2008, at 21:22, Lynn Barton wrote:

    > hfsFileType = [fileAttr valueForKey:NSFileHFSTypeCode];
    > modDate = [fileAttr valueForKey:NSFileModificationDate];

    Don't you mean:

        hfsFileType = [fileAttr objectForKey:NSFileHFSTypeCode];
        modDate = [fileAttr objectForKey:NSFileModificationDate];

    ?
  • On 21 May '08, at 9:22 PM, Lynn Barton wrote:

    > I am getting the date OK,
    > but not the type code, which should be “TEXT” for text files and
    > might be
    > “WBBN” for a Microsoft Word document.

    Most files don't have HFS type or creator codes anymore, because Cocoa
    apps don't usually set them. (Word probably does, because it's been
    around forever.) And downloaded files generally don't have them either
    unless they were encoded with StuffIt or MacBinary.

    In general you're better off checking the filename extension. (I know.
    I used to be rabidly in favor of HFS types over extensions, but I gave
    up that fight years ago...)

    —Jens
  • On 5/21/08 10:35 PM, Jens Alfke said:

    > In general you're better off checking the filename extension. (I know.
    > I used to be rabidly in favor of HFS types over extensions, but I gave
    > up that fight years ago...)

    In general you're better off checking the UTI.
    <http://developer.apple.com/macosx/uniformtypeidentifiers.html>

    --
    ____________________________________________________________
    Sean McBride, B. Eng                <sean...>
    Rogue Research                        www.rogue-research.com
    Mac Software Developer              Montréal, Québec, Canada
  • The replies to my original question are appreciated, but they do not answer
    the question. Once my NSFileManager object has found a file of interest, why
    can I get the modification date with the key NSFileModificationDate (using
    objectForKey or valueForKey doesn't matter) but I can't get the OSType code
    with the key NSFileHFSTypeCode. Each time I try to access this data I get a
    different result. I know that the file has a type code because I can access
    it with another program.

    > From what I have read quickly since Sean McBride sent his comment, UTIs are
    not yet implemented to the point where I could get the UTI of every file on
    my computer.

    File attribute keys are found on page 48 of the pdf version of the document
    "NSFileManager Class Reference".

    On 5/22/08 1:43 PM, "Sean McBride" <sean...> wrote:

    > On 5/21/08 10:35 PM, Jens Alfke said:
    >
    >> In general you're better off checking the filename extension. (I know.
    >> I used to be rabidly in favor of HFS types over extensions, but I gave
    >> up that fight years ago...)
    >
    > In general you're better off checking the UTI.
    > <http://developer.apple.com/macosx/uniformtypeidentifiers.html>
    >
    > --
    > ____________________________________________________________
    > Sean McBride, B. Eng                <sean...>
    > Rogue Research                        www.rogue-research.com
    > Mac Software Developer              Montréal, Québec, Canada
    >
  • On May 22, 2008, at 16:37, Lynn Barton wrote:

    > I can't get the OSType code
    > with the key NSFileHFSTypeCode. Each time I try to access this data
    > I get a
    > different result

    Is it perhaps something to do with the fact that [fileAttributes
    objectForKey: NSFileHFSTypeCode] is documented to be a NSNumber
    object, so the actual type code would be [[fileAttributes
    objectForKey: NSFileHFSTypeCode] intValue]?
  • On May 22, 2008, at 5:08 PM, Quincey Morris wrote:

    >
    > On May 22, 2008, at 16:37, Lynn Barton wrote:
    >
    >> I can't get the OSType code
    >> with the key NSFileHFSTypeCode. Each time I try to access this data
    >> I get a
    >> different result
    >
    > Is it perhaps something to do with the fact that [fileAttributes
    > objectForKey: NSFileHFSTypeCode] is documented to be a NSNumber
    > object, so the actual type code would be [[fileAttributes
    > objectForKey: NSFileHFSTypeCode] intValue]?

    Since it's documented as returning an unsigned long, I'd use -
    unsignedLongValue or -[NSDictionary fileHFSTypeCode] which returns an
    OSType directly.

    The OP also asked about converting this to a string, which you can do
    with NSFileTypeForHFSTypeCode() or UTCreateStringForOSType() if you're
    working with UTIs.  Doing a Spotlight search for kMDItemContentType ==
    public.plain-text might make more sense than iterating directories,
    unless you're only looking for files with a type code.

    --
    adam
  • On 5/22/08 4:37 PM, Lynn Barton said:

    > From what I have read quickly since Sean McBride sent his comment, UTIs are
    > not yet implemented to the point where I could get the UTI of every file on
    > my computer.

    Sure you can.  Use LSCopyItemAttributes() with kLSItemContentType.

    --
    ____________________________________________________________
    Sean McBride, B. Eng                <sean...>
    Rogue Research                        www.rogue-research.com
    Mac Software Developer              Montréal, Québec, Canada
  • On May 23, 2008, at 5:19 PM, Sean McBride wrote:

    > On 5/22/08 4:37 PM, Lynn Barton said:
    >
    >> From what I have read quickly since Sean McBride sent his comment,
    >> UTIs are
    >> not yet implemented to the point where I could get the UTI of every
    >> file on
    >> my computer.
    >
    > Sure you can.  Use LSCopyItemAttributes() with kLSItemContentType.
    >

    I've written a category on NSFileManager that, among other things,
    will do this.  Here's the relevant portion for you:

    __________________________________________________
    #import <Foundation/Foundation.h>

    @interface NSFileManager (DSFileAdditions)
    + (NSString *)UTIForFile:(NSString *)path;
    + (NSString *)UTIForURL:(NSURL *)url;
    @end

    @implementation NSFileManager (DSFileAdditions)

    + (NSString *)UTIForFile:(NSString *)path
    {
    return [self UTIForURL:[NSURL fileURLWithPath:path]];
    }

    + (NSString *)UTIForURL:(NSURL *)url
    {
    NSString *retval = nil;
    FSRefPtr fileRef = NULL;

    fileRef = calloc( 1, sizeof( FSRef ) );

    if ( (fileRef != NULL) && (url != nil) && [url isFileURL] &&
    (CFURLGetFSRef( (CFURLRef)url, fileRef ) == true) ) {
      CFStringRef theUTI = NULL;
      if ( LSCopyItemAttribute( fileRef, kLSRolesAll, kLSItemContentType,
    (CFTypeRef *)&theUTI ) == noErr ) {
      retval = [[(NSString *)theUTI copy] autorelease];
      CFRelease( theUTI );
      }
    }

    if ( fileRef != NULL )
      free( fileRef );

    return retval;
    }
    __________________________________________________

    I *think* this code should work fine under GC (for anyone using it),
    but you should probably test it first as I haven't.

    --------------------------------------
    Darkshadow
    (aka Michael Nickerson)
    http://www.nightproductions.net
  • On 23 May 2008, at 23:30, <cocoa-dev-request...> wrote:
    >
    >> From what I have read quickly since Sean McBride sent his comment,
    >> UTIs are
    >> not yet implemented to the point where I could get the UTI of
    >> every file on
    >> my computer.
    >
    > Sure you can.  Use LSCopyItemAttributes() with kLSItemContentType.

    How do you know this?

    I just read "An Overview of UTI Functions" in the "Uniform Type
    Identifiers Overview" and did find no mention at all of this.
    (Actually I had been looking for something like LSCopyItemAttribute
    (), concluded that this did not exist, further concluded that this
    nice technology obviously was only half implemented by Apple and that
    I had to wait another year or two before it was usable).

    Kind regards,

    Gerriet.
  • On 5/24/08 8:10 AM, Gerriet M. Denkmann said:

    >>> From what I have read quickly since Sean McBride sent his comment,
    >>> UTIs are
    >>> not yet implemented to the point where I could get the UTI of
    >>> every file on
    >>> my computer.
    >>
    >> Sure you can.  Use LSCopyItemAttributes() with kLSItemContentType.
    >
    > How do you know this?
    >
    > I just read "An Overview of UTI Functions" in the "Uniform Type
    > Identifiers Overview" and did find no mention at all of this.
    > (Actually I had been looking for something like LSCopyItemAttribute
    > (), concluded that this did not exist, further concluded that this
    > nice technology obviously was only half implemented by Apple and that
    > I had to wait another year or two before it was usable).

    Gerriet,

    I forget how I learned this originally.  In fact, it took me several
    minutes to find the answer for you in the docs.  I guess this is an
    example of how the docs could be improved.  And yes, UTI support has
    been slow in coming.  It was only in 10.5 that NSOpenPanel got support
    for them, for example.  However, UTI support is now pretty good as of
    10.5.  Beware though that the UTI mechanism has no way to deal with
    conflicting file extensions.  So if two different application declare
    different UTIs for the same extension, you don't know which UTI you'll get!

    --
    ____________________________________________________________
    Sean McBride, B. Eng                <sean...>
    Rogue Research                        www.rogue-research.com
    Mac Software Developer              Montréal, Québec, Canada
previous month may 2008 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Go to today