Подтвердить что ты не робот

В С#, как я могу узнать тип файла из байта []?

У меня есть байтовый массив, заполненный из загруженного файла. Но в другой части кода мне нужно знать этот тип файла, загружаемый из байта [], поэтому я могу отобразить правильный тип содержимого в браузере!

Спасибо!!

4b9b3361

Ответ 1

Не уверен, но, возможно, вам стоит исследовать магические числа .

Update: Читая об этом, я не думаю, что он очень надежный, хотя.

Ответ 2

Как уже упоминалось, магия MIME - единственный способ сделать это. Многие платформы предоставляют обновленные и надежные магические файлы MIME и код, чтобы сделать это эффективно. Единственный способ сделать это в .NET без какого-либо стороннего кода - использовать FindMimeFromData из urlmon.dll. Вот как:

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

Здесь используется детектор MIME Internet Explorer. Это тот же код, который используется IE для отправки типа MIME вместе с загруженными файлами. Список типов MIME, поддерживаемых urlmon.dll, можно посмотреть в . Единственное, на что нужно обратить внимание, это image/pjpeg и image/x-png, которые являются нестандартными. В моем коде я заменяю их на image/jpeg и image/png.

Ответ 3

Вы не можете знать это из потока байтов, но вы можете сохранить тип MIME, когда вы изначально заполняете byte[].

Ответ 4

Короткий ответ: вы не можете

Более длинный ответ. Обычно программы используют расширение файла, чтобы узнать, с каким типом файлов они имеют дело. Если у вас нет этого расширения, вы можете делать только догадки... например, вы можете посмотреть первые несколько байтов и проверить, распознаете ли вы известный заголовок (тэг объявления XML, например, растровый или JPEG-заголовок). Но это всегда будет угадать в конце: без некоторых метаданных или информации о содержимом, массив байтов просто бессмыслен...

Ответ 5

Напоминает мне об этом в тот день, когда мы, например, "некоторые люди" делили 50-мегабайтные rar файлы на ранних сайтах бесплатного хостинга изображений, просто добавляя расширение .gif к имени файла .rar.

Очевидно, что если вы публично выглядите, и вы ожидаете определенного типа файла, и вы должны быть уверены, что это тот тип файла, то вы не можете просто доверять расширению.

С другой стороны, если ваше приложение не будет иметь никаких оснований не доверять загруженному расширению и типу MIME, тогда просто получите их, когда файл будет загружен, как ответы, полученные вами от @rossfabircant и @RandolphPotter. создайте тип с байтом [], а также исходное расширение или тип mimetype и передайте его.

Если вам нужно убедиться, что файл на самом деле является определенным ожидаемым типом, например, допустимым .jpeg или .png, вы можете попытаться интерпретировать файл как эти типы и посмотреть, успешно ли он открывается. (System.Drawing.Imaging.ImageFormat)

Если вы пытаетесь классифицировать файл только из двоичного содержимого, и это может быть любой формат во всем мире, это действительно сложная проблема с открытым концом, и нет 100% надежного способа сделать это, Вы можете вызвать TrID против него, и есть вероятные аналогичные инструменты судебной экспертизы, используемые следователями правоохранительных органов, если вы сможете найти (и позволить себе) их.

Если вам не нужно делать это трудным путем, не делайте этого.

Ответ 6

Ты не хочешь этого делать. Вызовите Path.GetExtension, когда файл загружен, и передайте расширение с байтом [].

Ответ 7

Если у вас есть ограниченное количество ожидаемых типов файлов, которые вы хотите поддержать, магические числа могут быть способом.

Простым способом проверки является просто открыть файлы примеров с помощью текстового/шестнадцатеричного редактора и изучить ведущие байты, чтобы увидеть, есть ли там что-то, что вы можете использовать, чтобы отличать/отбрасывать файлы из поддерживаемого набора.

Если, с другой стороны, вы хотите распознать любой произвольный тип файла, да, как все уже заявили, жестко.

Ответ 8

Используя свойство System.Drawing.Image 'RawFormat.Guid', вы можете обнаружить MIME-тип изображений.

но я не уверен, как найти другие типы файлов.

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

ОБНОВЛЕНИЕ:, вы можете попробовать взглянуть на это сообщение

Используя .NET, как вы можете найти тип mime файла на основе имени файла, а не расширения

Ответ 9

Если вы знаете это System.Drawing.Image, вы можете сделать:

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