Dans C#, Comment puis-je connaître le type de fichier à partir d'un octet[]?

j'ai un tableau d'octets remplie à partir d'un fichier téléchargé. Mais, dans une autre partie du code, j'ai besoin de connaître ce type de fichier téléchargé à partir de l'octet[] pour que je puisse rendre le bon type de contenu au navigateur!

Merci!!

25
demandé sur AndreMiranda 2009-10-31 19:25:42

10 réponses

Pas sûr, mais peut-être que vous devriez enquêter sur nombres magiques .

mise à Jour: En lisant ça, Je ne pense pas que ce soit très fiable.

8
répondu Carles Company 2009-10-31 18:48:35

comme mentionné, la magie MIME est la seule façon de le faire. De nombreuses plateformes fournissent des fichiers magiques MIME robustes et à jour et du code pour le faire efficacement. La seule façon de le faire dans .NET sans aucun code tiers est d'utiliser FindMimeFromData de urlmon.DLL. Voici comment:

public static int MimeSampleSize = 256;

public static string DefaultMimeType = "application/octet-stream";

[DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
private extern static uint FindMimeFromData(
    uint pBC,
    [MarshalAs(UnmanagedType.LPStr)] string pwzUrl,
    [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
    uint cbSize,
    [MarshalAs(UnmanagedType.LPStr)] string pwzMimeProposed,
    uint dwMimeFlags,
    out uint ppwzMimeOut,
    uint dwReserverd
);

public static string GetMimeFromBytes(byte[] data) {
    try {
        uint mimeType;
        FindMimeFromData(0, null, data, (uint)MimeSampleSize, null, 0, out mimeType, 0);

        var mimePointer = new IntPtr(mimeType);
        var mime = Marshal.PtrToStringUni(mimePointer);
        Marshal.FreeCoTaskMem(mimePointer);

        return mime ?? DefaultMimeType;
    }
    catch {
        return DefaultMimeType;
    }
}

utilise le détecteur MIME Internet Explorer. C'est le même code utilisé par IE pour envoyer un type MIME avec des fichiers téléchargés. Vous pouvez voir la liste des types MIME supporté par urlmon.dll . Une chose à surveiller est image/pjpeg et image/x-png qui ne sont pas standard. Dans mon code, je les remplace par image/jpeg et image/png .

19
répondu mroach 2011-03-31 12:42:08

vous ne pouvez pas le connaître à partir du flux octet, mais vous pouvez stocker le type MIME lorsque vous peuplez initialement le byte[] .

8
répondu 2009-10-31 16:28:53

brève réponse: vous ne pouvez pas

réponse plus longue: habituellement, les programmes utilisent l'extension de fichier pour savoir quel type de fichier ils traitent. Si vous n'avez pas cette extension, vous pouvez seulement faire des suppositions... par exemple, vous pouvez regarder les premiers octets et vérifier si vous reconnaissez un en-tête bien connu (étiquette de déclaration XML par exemple, ou en-tête bitmap ou JPEG). Mais ce sera toujours une conjecture à la fin : sans métadonnées ou informations sur le contenu, un le tableau des octets n'a pas de sens...

7
répondu Thomas Levesque 2011-05-09 07:57:22

si vous savez que c'est un System.Drawing.Image , vous pouvez faire:

public static string GeMimeTypeFromImageByteArray(byte[] byteArray)
{
   using (MemoryStream stream = new MemoryStream(byteArray))
   using (Image image = Image.FromStream(stream))
   {
       return ImageCodecInfo.GetImageEncoders().First(codec => codec.FormatID == image.RawFormat.Guid).MimeType;
   }
}
3
répondu yazanpro 2017-12-08 19:23:03

me rappelle de l'époque où nous, euh" certaines personnes " utilisé pour partager des fichiers 50m RAM sur les premiers sites d'hébergement d'image libre, en ajoutant juste le .gif extension de l' .nom de fichier rar.

clairement si vous êtes face au public et que vous attendez un certain type de fichier, et que vous devez être sûr que c'est ce type de fichier, alors vous ne pouvez pas juste faire confiance à l'extension.

, d'autre part, si votre application n'aurait aucune raison de la méfiance de l'téléchargés extension et / ou type MIME, puis il suffit de les obtenir lorsque le fichier est téléchargé comme les réponses que vous avez reçues de @rossfabricant et @RandolphPotter. créez un type qui a le byte[], ainsi que l'extension d'origine ou mimetype, et faites circuler cela.

si vous avez besoin de vérifier que le fichier est réellement un certain type attendu comme un valide .jpeg, ou .png vous pouvez essayer d'interpréter le fichier que ces types et de voir s'il s'ouvre correctement. (Système.Dessin.L'imagerie.ImageFormat)

Si vous essayez de classer le fichier qu'à partir du contenu binaire, et il pourrait être n'importe quel format dans le monde entier, c'est vraiment une question difficile, ouvertes problème et il n'est pas fiable à 100%. Vous pouvez invoquer TrID contre elle, et il y a probablement des outils judiciaires similaires utilisés par les enquêteurs d'application de la loi si vous pouvez les trouver (et se permettre).

Si vous n'avez pas à faire à la dure, ne le font pas.

2
répondu DanO 2009-11-04 16:37:55

Vous ne voulez pas le faire de cette façon. Appelez Le Chemin.GetExtension lorsque le fichier est téléchargé, et passer l'extension autour avec le byte[].

1
répondu RossFabricant 2009-10-31 16:32:49

si vous avez un nombre limité de types de fichiers attendus que vous voulez prendre en charge, magic numbers peut être la solution.

une façon simple de vérifier est d'ouvrir des fichiers d'exemple avec un éditeur text/hex, et d'étudier les octets de tête pour voir s'il y a quelque chose là que vous pouvez utiliser pour différencier/rejeter des fichiers de l'ensemble supporté.

si, d'un autre côté, vous cherchez à reconnaître un type de fichier arbitraire, oui, comme tout le monde l'a déjà dit, difficile.

0
répondu Oskuro 2012-06-20 14:51:39

utilisant le système.Dessin.Image ' RawFormat.Propriété de Guid vous pouvez détecter le type MIME D'Images.

mais je ne sais pas comment trouver d'autres types de fichiers.

http://www.java2s.com/Code/CSharp/Network/GetImageMimeType.htm

mise à JOUR: vous pouvez essayer de prendre un coup d'oeil sur ce post

avec .NET, comment trouver le type mime d'un fichier basé sur la signature de fichier non l'extension

0
répondu Muhammad Omar ElShourbagy 2017-05-23 11:47:23

si vous connaissez l'extension du nom de fichier, peut être Système.Web.Le MimeMapping fera l'affaire:

MimeMapping.GetMimeMapping(fileDisplayNameWithExtension)

Je l'ai utilisé dans L'Action MVC comme ceci:

return File(fileDataByteArray, MimeMapping.GetMimeMapping(fileDisplayNameWithExtension), fileDisplayNameWithExtension);
0
répondu Yasser Sobhdel 2018-08-08 15:18:42