2011-04-28 3 views
23

J'ai réussi à trouver le type de fichier étendu d'un fichier spécifié (image JPEG, image TIFF, ...) mais je cherche quelque chose de plus générique qui peut catégoriser les fichiers dans "grandes catégories" "comme des images, moovies, fichiers texte, ... Y at-il un moyen d'y parvenir dans le cacao (ou objectif-c)?Obtenir le type d'un fichier dans Cocoa

Merci pour votre aide,

Répondre

63

Vous pouvez utiliser Uniform Type Identifiers. Puisque les UTI sont organisées en hiérarchies, une possibilité est de vérifier si l'UTI préférée pour un fichier donné est conforme à une UTI de niveau supérieur, par ex. public.image pour les images ou public.movie pour les films. Le cadre des services de base comprend des fonctions qui fonctionnent sur les infections urinaires ainsi que des constantes représentant des infections urinaires connues.

Par exemple, en travaillant sur les extensions de nom de fichier:

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

Si vous avez un type MIME au lieu d'une extension de nom de fichier, vous pouvez utiliser kUTTagClassMIMEType au lieu de kUTTagClassFilenameExtension. Pour une liste des UTI connus, voir this document.

+1

C'était exactement ce que je cherchais. Merci! –

+3

Si vous êtes comme moi et que vous rencontrez des problèmes pour obtenir l'extension de fichier conforme à la bonne UTI, assurez-vous de ne pas ajouter l'extension de fichier avec un point! Vous devriez passer "jpg" et PAS ".jpg"! – Will

+0

Malheureusement, la vérification de l'UTI semble fonctionner uniquement avec certains types/fichiers vidéo. Cela fonctionne bien avec les conteneurs MP4 (par exemple), mais cela ne fonctionne pas avec les conteneurs MKV. 'UTTypeCreatePreferredIdentifierForTag' renvoie un type dynamique commençant par le préfixe' dyn' lorsqu'il ne trouve pas d'UTI approprié (donc pour MKV, par exemple). – Alex

3

Ceci obtiendra le type de fichier.

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

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

+0

Ceci est celui que j'utilise et il renvoie "image JPEG", "MP3 Audio" au lieu de "image", "audio", "film", .... –

+0

LSCopyKindStringForURL est maintenant obsolète. [This] (http://stackoverflow.com/questions/37765413/how-do-you-get-the-finder-kind-for-a-file-in-2016#37765537) a été utile pour moi. – Todd

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

Exemple pour vérifier si un chemin est un type d'image, peut être changé pour correspondre à d'autres classes d'infection urinaire. Notez la note technique technique Q & Un QA1518 utilise FSPathMakeRef qui est maintenant déprécié pour obtenir l'uti via LSCopyItemAttributes - la solution NSWorkspace ci-dessus est le meilleur moyen d'obtenir l'UTI alors vous avez juste besoin d'ajouter du code pour comparer avec une liste d'UTIs: le tableau de correspondance peut être pré allouée et initialisée/libéré ailleurs si on le souhaite)

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

On peut également déterminer le type d'image sans se fondant sur l'extension du chemin avec CGImageSource (partie du cadre ImageIO).

L'exemple suivant utilise une URL de fichier, mais vous pouvez également créer une source d'image à partir d'un 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; 
} 

La valeur de retour sera une constante que vous pouvez comparer avec les valeurs d'identificateur de type uniforme déclarées dans CoreServices/MobileCoreServices (par exemple, kUTTypeJPEG, kUTTypeGIF, etc). La cerise sur le gateau: vous pouvez passer un "hint" optionnel si vous avez des raisons d'anticiper un type de fichier ou un autre. Combinez cette approche avec Bavarious 'et vous aurez une machine de détection de format d'image maigre, moyenne.

Questions connexes