2011-04-28 65 views
23

我成功找到了指定文件(JPEG图像,TIFF图像,...)的扩展文件类型,但我在寻找更通用的东西,可以将文件分类为“大型文件“像图像,moovies,文本文件,... 它有一种方法来实现可可(或Objective-C)这个?获取Cocoa中的文件类型

感谢您的帮助,

回答

63

你可以使用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。请参阅this document

+1

这正是我正在寻找的。谢谢! – 2011-04-28 09:48:44

+3

如果您喜欢我并且在获取文件扩展名符合正确的UTI时遇到问题,请确保您不要将文件扩展名加上一段时间!你应该传递“jpg”而不是“.jpg”! – Will 2013-12-16 15:06:01

+0

不幸的是,检查UTI似乎只适用于某些视频类型/文件。它适用于MP4容器(例如),但不适用于MKV容器。当UTTypeCreatePreferredIdentifierForTag无法找到合适的UTI时(例如MKV),返回一个以'dyn'前缀开头的动态类型。 – Alex 2015-04-21 12:38:03

3

这会得到'kind'文件。

+ (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

+0

这是我正在使用的一个,它返回“JPEG图像”,“MP3音频”而不是“图像”,“音频”,“电影”,.... – 2011-04-28 06:46:04

+0

LSCopyKindStringForURL现已弃用。 [这](http://stackoverflow.com/questions/37765413/how-do-you-get-the-finder-kind-for-a-file-in-2016#37765537)对我很有帮助。 – Todd 2017-01-16 12:20:43

11
[[NSWorkspace sharedWorkspace] typeOfFile:pathToFile error:nil] 
5

检查路径是否为图像类型的示例可以更改为与其他UTI类匹配。请注意技术说明技术Q & 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; 
} 
6

还可以判断图像类型而不依靠路径扩展与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相结合,您将拥有一台精益平均图像格式检测机器。