【问题标题】:Get the type of a file in Cocoa获取 Cocoa 中文件的类型
【发布时间】:2011-08-14 10:36:09
【问题描述】:

我成功找到了指定文件的扩展文件类型(JPEG 图像、TIFF 图像……),但我正在寻找更通用的东西,可以将文件分类为“大类”,如图像、电影、文本文件, ... 有没有办法在可可(或objective-c)中实现这一点?

感谢您的帮助,

【问题讨论】:

    标签: objective-c cocoa file


    【解决方案1】:

    您可以使用Uniform Type Identifiers。由于 UTI 被组织成层次结构,一种可能性是检查给定文件的首选 UTI 是否符合顶级 UTI,例如public.image 用于图像或public.movie 用于电影。核心服务框架包括在 UTI 上运行的函数以及表示已知 UTI 的常量。

    例如,处理文件扩展名:

    NSString *file = @"…"; // path to some file
    CFStringRef fileExtension = (CFStringRef) [file pathExtension];
    CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
    
    if (UTTypeConformsTo(fileUTI, kUTTypeImage)) NSLog(@"It's an image");
    else if (UTTypeConformsTo(fileUTI, kUTTypeMovie)) NSLog(@"It's a movie");
    else if (UTTypeConformsTo(fileUTI, kUTTypeText)) NSLog(@"It's text");
    
    CFRelease(fileUTI);
    

    如果您有 MIME 类型而不是文件扩展名,则可以使用 kUTTagClassMIMEType 而不是 kUTTagClassFilenameExtension

    有关已知 UTI 的列表,请参阅 this document

    【讨论】:

    • 这正是我想要的。谢谢!
    • 如果您像我一样在使文件扩展名符合正确的 UTI 时遇到问题,请确保您不要在文件扩展名前加上句点!你应该传递“jpg”而不是“.jpg”!
    • 不幸的是,UTI 的检查似乎只适用于某些视频类型/文件。它适用于 MP4 容器(例如),但不适用于 MKV 容器。 UTTypeCreatePreferredIdentifierForTag 在找不到合适的 UTI 时返回以 dyn 前缀开头的动态类型(例如,对于 MKV)。
    • 你好什么类型等于doc/docx?谢谢
    【解决方案2】:
    [[NSWorkspace sharedWorkspace] typeOfFile:pathToFile error:nil]
    

    【讨论】:

      【解决方案3】:

      检查路径是否为图像类型的示例,可以更改以匹配其他 UTI 类。请注意技术说明技术问答 QA1518 使用 FSPathMakeRef 现在已弃用以通过 LSCopyItemAttributes 获取 uti - 上面的 NSWorkspace 解决方案是获取 UTI 的最佳方法,然后您只需添加代码以与 UTI 列表进行比较:(匹配如果需要,可以在其他地方预分配和初始化/释放数组)

      - (BOOL)isImageFile:(NSString*)filePath
      {
      /* get an array of utis to match against, this gets supported CG/NS image formats */
      
      CFArrayRef supportedTypes = CGImageSourceCopyTypeIdentifiers();
      CFIndex    typeCount      = CFArrayGetCount(supportedTypes);
      
      /* get the uti of the filepath and check against the list with the UTI API */
      
      BOOL isImage     = NO;
      NSString * uti   = [[NSWorkspace sharedWorkspace] typeOfFile:filePath error:nil];
      
      if ( uti != nil){
          for (CFIndex i = 0; i < typeCount; i++)
          {
              CFStringRef supportedUTI = CFArrayGetValueAtIndex(supportedTypes, i);
              if (UTTypeConformsTo(supportedUTI, CFSTR("public.image")))
              {
                  if (UTTypeConformsTo((CFStringRef)uti, supportedUTI))
                  {
                      isImage = YES;
                      break;
                  }
              }
          } // i
      }
      /* clean up */
      CFRelease(supportedTypes);
      return isImage;
      }
      

      【讨论】:

      【解决方案4】:

      您还可以在不依赖 CGImageSource(ImageIO 框架的一部分)的路径扩展的情况下确定图像类型。

      以下示例使用文件 URL,但您也可以从 CFDataRef 创建图像源。

      CFStringRef typeOfImageAtURL(NSURL *imageURL) {
          const void * keys[] = { kCGImageSourceShouldCache };
          const void * values[] = { kCFBooleanFalse };
          CFDictionaryRef options = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);
          CGImageSourceRef imageSource = CGImageSourceCreateWithURL((__bridge CFURLRef)imageURL, options);
          CFStringRef imageType = CGImageSourceGetType(imageSource);
          CFRelease(options);
          CFRelease(imageSource);
          return imageType;
      }
      

      返回值将是一个常量,您可以将其与 CoreServices/MobileCoreServices 中声明的统一类型标识符值(例如 kUTTypeJPEG、kUTTypeGIF 等)进行比较。

      锦上添花:如果您有理由预期一种或另一种文件类型,您可以传入一个可选的“提示”UTI。将此方法与 Bavarious 相结合,您将拥有一台精巧、平均的图像格式检测机器。

      【讨论】:

        【解决方案5】:

        这将获得文件的“种类”。

        + (NSString *)humanReadableFileType:(NSString *)path{
            NSString *kind = nil;
            NSURL *url = [NSURL fileURLWithPath:[path stringByExpandingTildeInPath]];
            LSCopyKindStringForURL((CFURLRef)url, (CFStringRef *)&kind);
            return kind ? [kind autorelease] : @"";
        }
        

        来源http://importantshock.wordpress.com/2007/01/07/cocoa-snippet-finding-a-files-kind/#post-19

        【讨论】:

        • 这是我正在使用的,它返回 "JPEG image", "MP3 Audio" 而不是 "image", "audio","movie" , ....
        • LSCopyKindStringForURL 现在已弃用。 This 对我很有帮助。
        猜你喜欢
        • 1970-01-01
        • 2011-05-20
        • 1970-01-01
        • 2021-10-13
        • 2018-12-01
        • 2010-11-29
        • 1970-01-01
        • 2017-05-08
        • 1970-01-01
        相关资源
        最近更新 更多