Obter o tipo de um arquivo no cacau

Eu consegui encontrar o tipo de arquivo estendido de um arquivo especificado (imagem JPEG, TIFF Image, …), mas estou procurando algo mais genérico que pode categorizar arquivos em “grandes categorias” como imagens, moovies, arquivos de texto, .. Existe uma maneira de conseguir isso no cacau (ou objective-c)?

Obrigado pela ajuda,

Você poderia usar identificadores de tipo uniforme . Como as ITUs são organizadas em hierarquias, uma possibilidade é verificar se a UTI preferencial de um determinado arquivo está de acordo com uma UTI de nível superior, por exemplo, public.image para imagens ou public.movie para filmes. A estrutura dos Serviços Principais inclui funções que operam em UTIs, assim como constantes que representam UTIs conhecidas.

Por exemplo, trabalhando em extensões de nome de arquivo:

 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); 

Se você tiver um tipo MIME em vez de uma extensão de nome de arquivo, poderá usar kUTTagClassMIMEType vez de kUTTagClassFilenameExtension .

Para uma lista de UTIs conhecidas, consulte este documento .

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

Você também pode determinar o tipo de imagem sem depender da extensão do caminho com CGImageSource (parte da estrutura do ImageIO).

O exemplo a seguir usa um URL de arquivo, mas você também pode criar uma fonte de imagem a partir de um 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; } 

O valor de retorno será uma constante que você pode comparar com os valores de identificador de tipo uniformes declarados em CoreServices / MobileCoreServices (por exemplo, kUTTypeJPEG, kUTTypeGIF, etc).

A cereja no topo do bolo: você pode passar em uma UTI “sugestão” opcional se tiver motivos para antecipar um tipo de arquivo ou outro. Combine essa abordagem com o Bavarious ‘e você terá uma máquina de detecção de formato de imagem simples.

Exemplo para verificar se um caminho é um tipo de imagem, pode ser alterado para corresponder a outras classs de UTI. Observe que o QA1518 técnico da Tech Note usa o FSPathMakeRef que agora está obsoleto para obter o uti via LSCopyItemAttributes – a solução de NSWorkspace acima é a melhor maneira de obter o UTI, basta adicionar código para comparar com uma lista de UTIs: array pode ser pré alocado e inicializado / liberado em outro lugar, se desejado)

 - (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; } 

Isto irá obter o ‘tipo’ de arquivo.

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

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