获取Cocoa中的文件类型

AP.*_*AP. 27 cocoa file objective-c

我成功地找到了指定文件的扩展文件类型(JPEG图像,TIFF图像,...),但我正在寻找更通用的东西,可以对图像,moovies,文本文件等"大导弹"中的文件进行分类.有没有办法在可可(或客观-c)中实现这一目标?

谢谢你的帮助,

小智 69

您可以使用统一类型标识符.由于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);
Run Code Online (Sandbox Code Playgroud)

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

有关已知UTI的列表,请参阅此文档.

  • 如果您和我一样,并且在使文件扩展名符合正确的UTI时遇到问题,请确保您没有在文件扩展名前加上句号!你应该传递"jpg"而不是".jpg"! (3认同)

use*_*274 12

[[NSWorkspace sharedWorkspace] typeOfFile:pathToFile error:nil]
Run Code Online (Sandbox Code Playgroud)


小智 6

检查路径是否为图像类型的示例可以更改为与其他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;
}
Run Code Online (Sandbox Code Playgroud)


nze*_*zer 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;
}
Run Code Online (Sandbox Code Playgroud)

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

锦上添花:如果您有理由预期某种文件类型或其他类型,您可以传入可选的"提示"UTI.将这种方法与Bavarious'相结合,你将拥有一个精简,平均的图像格式检测机器.