2011-04-28 69 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相結合,您將擁有一臺精益平均圖像格式檢測機器。