Domanda

Ho un array di byte riempita da un file caricato. Ma, in un'altra parte del codice, ho bisogno di sapere questo tipo di file caricato dal byte [] in modo da poter rendere il corretto tipo di contenuto al browser!

Grazie !!

È stato utile?

Soluzione

Non è sicuro, ma forse si dovrebbe indagare su Magic Numbers .

Aggiornamento: Leggere a questo proposito, non credo che sia molto affidabile, però.

Altri suggerimenti

Come già detto, la magia MIME è l'unico modo per fare questo. Molte piattaforme forniscono up-to-date e robusti file magici MIME e il codice per fare questo in modo efficace. L'unico modo per fare questo in .NET senza alcun codice 3rd party è quello di utilizzare FindMimeFromData da urlmon.dll. Ecco come:

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

Questo utilizza il rilevatore di Internet Explorer MIME. Questo è lo stesso codice utilizzato da IE per inviare un tipo MIME con i file caricati. È possibile visualizzare l'elenco di tipi MIME supportati da urlmon .dll . Una cosa a cui prestare attenzione è image/pjpeg e image/x-png che sono non standard. Nel mio codice sostituisco questi con image/jpeg e image/png.

Non si può sapere che dal flusso di byte, ma è possibile memorizzare il tipo MIME quando inizialmente popolare il byte[].

Risposta breve: non è possibile

Più rispondere: Di solito, i programmi di utilizzare l'estensione del file per sapere che tipo di file con cui hanno a che fare. Se non si dispone di tale estensione, si può solo fare congetture ... per esempio, si poteva guardare i primi byte e verificare se si riconosce un colpo di testa ben noto (tag dichiarazione XML per esempio, o bitmap o JPEG intestazione ). Ma che sarà sempre una supposizione, alla fine: senza qualche metadati o informazioni sul contenuto, un array di byte è solo privo di significato ...

Se sai che è un System.Drawing.Image , si può fare:

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

Se si conosce l'estensione del nome del file, possono essere System.Web.MimeMapping farà il trucco:

MimeMapping.GetMimeMapping(fileDisplayNameWithExtension)

L'ho usato in azione MVC in questo modo:

return File(fileDataByteArray, MimeMapping.GetMimeMapping(fileDisplayNameWithExtension), fileDisplayNameWithExtension);

Mi ricorda nel giorno che, er um "alcune persone" utilizzato per condividere file rar 50MB sull'immagine presto libera siti di hosting, con la sola aggiunta l'estensione .gif al nome del file .rar.

Chiaramente se siete di fronte pubblico e il vostro sono in attesa di un determinato tipo di file, e bisogna essere sicuri che sia quel tipo di file, quindi non si può semplicemente fidarsi l'estensione.

D'altra parte, se la vostra applicazione non avrebbe alcun motivo di diffidare il tipo di estensione e caricato o MIME, poi basta ottenere quelle quando il file viene caricato come le risposte che hai ricevuto da @rossfabircant e @RandolphPotter. creare un tipo che ha il byte [], nonché l'estensione o mimetype originale, e passare tale intorno.

Se è necessario verificare che il file è in realtà un certo tipo previsto come un .jpeg valida, o .png si può cercare di interpretare il file come quei tipi e vedere se si apre con successo. (System.Drawing.Imaging.ImageFormat)

Se si sta tentando di classificare il file solo dai contenuti binari, e potrebbe essere qualsiasi formato in tutto il mondo, che è davvero un duro, problema aperto e non c'è modo affidabile al 100% per farlo . Si potrebbe invocare TrID contro di esso, e ci sono probabilmente simili forensi strumenti utilizzati dalle forze dell'ordine gli investigatori se è possibile trovare (e permettersi) di loro.

Se non si hanno a che fare nel modo più difficile, non lo fanno.

Non si vuole fare in questo modo. Chiama Path.GetExtension quando viene caricato il file, e passare il prolungamento in giro con il byte [].

Se si dispone di un numero limitato di tipi di file che ci si attende che si desidera supportare, numeri magici può essere la strada da percorrere.

Un modo semplice per controllare è quello di solo file di esempio aperti con un editor di testo / esadecimale, e studiare i byte che portano a vedere se c'è qualcosa che si può usare per differenziare / eliminare i file dal set supportato.

Se, d'altra parte, si sta cercando di riconoscere qualsiasi tipo di file arbitrari, sì, come tutti hanno detto già, dura.

utilizzando la proprietà del System.Drawing.Image 'RawFormat.Guid' è possibile rilevare MIME tipo di immagini.

, ma non sono sicuro come trovare altri tipi di file.

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

UPDATE: si può provare a prendere uno sguardo su questo post

Uso .NET, come si può trovare il tipo MIME di un file in base alla firma file non l'estensione

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top