【发布时间】:2011-08-14 10:36:09
【问题描述】:
我成功找到了指定文件的扩展文件类型(JPEG 图像、TIFF 图像……),但我正在寻找更通用的东西,可以将文件分类为“大类”,如图像、电影、文本文件, ... 有没有办法在可可(或objective-c)中实现这一点?
感谢您的帮助,
【问题讨论】:
标签: objective-c cocoa file
我成功找到了指定文件的扩展文件类型(JPEG 图像、TIFF 图像……),但我正在寻找更通用的东西,可以将文件分类为“大类”,如图像、电影、文本文件, ... 有没有办法在可可(或objective-c)中实现这一点?
感谢您的帮助,
【问题讨论】:
标签: objective-c cocoa file
您可以使用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。
【讨论】:
UTTypeCreatePreferredIdentifierForTag 在找不到合适的 UTI 时返回以 dyn 前缀开头的动态类型(例如,对于 MKV)。
[[NSWorkspace sharedWorkspace] typeOfFile:pathToFile error:nil]
【讨论】:
检查路径是否为图像类型的示例,可以更改以匹配其他 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;
}
【讨论】:
您还可以在不依赖 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 相结合,您将拥有一台精巧、平均的图像格式检测机器。
【讨论】:
这将获得文件的“种类”。
+ (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
【讨论】: