Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / c# Определить тип файла из byte[] / 13 сообщений из 13, страница 1 из 1
29.07.2016, 13:17
    #39282698
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
Здравствуйте.

Подскажите пожалуйста, что я не так делаю? Код рабочий.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
public static FileItemFormat GetIconAndFileExtension(byte[] streamFile)
{
     var memoryStream = new MemoryStream(streamFile);
     var buffer = new byte[256];
     if (memoryStream.Length >= 256)
         memoryStream.Read(buffer, 0, 256);
     else
         memoryStream.Read(buffer, 0, (int)memoryStream.Length);

     try
     {
          UInt32 mimetype;
          FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
          var mimeTypePtr = new IntPtr(mimetype);
          var mimetypeOfFile = Marshal.PtrToStringUni(mimeTypePtr);
          Marshal.FreeCoTaskMem(mimeTypePtr);
          if (!string.IsNullOrEmpty(mimetypeOfFile))
          {
               switch (mimetypeOfFile)
               {
                    case "application/pdf": // .pdf
                    case "application/octet-stream": // .doc
                    case "application/x-zip-compressed": // .docx
                    case "application/x-zip-compressed": // .xlsx
               }
         }
    }
    catch (Exception ex)
    {
         MessageBox.Show("Ошибка обработки расширения файла!" + ex.Message);
    }
    return null;
}


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



Я выбираю запускаю в алгоритм файл docx и xlsx и они и они у меня имеют один и тот же заголовок application/x-zip-compressed. Почему так?
...
Рейтинг: 0 / 0
29.07.2016, 13:33
    #39282720
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
NechtoКод рабочий.

Вы хотите сказать, что это компилируется?
Nechto
Код: c#
1.
2.
3.
4.
5.
6.
7.
switch (mimetypeOfFile)
               {
                    case "application/pdf": // .pdf
                    case "application/octet-stream": // .doc
                    case "application/x-zip-compressed": // .docx
                    case "application/x-zip-compressed": // .xlsx
               }
...
Рейтинг: 0 / 0
29.07.2016, 13:47
    #39282741
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
Nechto,
ну а запилить с http://www.pinvoke.net/default.aspx/urlmon.findmimefromdata
не судьба?
два копипаста

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
  [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
        static extern int FindMimeFromData(IntPtr pBC,
                [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
               [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)]
        byte[] pBuffer,
                int cbSize,
                   [MarshalAs(UnmanagedType.LPWStr)]  string pwzMimeProposed,
                int dwMimeFlags,
                out IntPtr ppwzMimeOut,
                int dwReserved);

        public static string getMimeFromFile(string file)
        {
            IntPtr mimeout;
            if (!System.IO.File.Exists(file))
                throw new FileNotFoundException(file + " not found");

            int MaxContent = (int)new FileInfo(file).Length;
            if (MaxContent > 4096) MaxContent = 4096;
            FileStream fs = File.OpenRead(file);


            byte[] buf = new byte[MaxContent];
            fs.Read(buf, 0, MaxContent);
            fs.Close();
            int result = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, null, 0, out mimeout, 0);

            if (result != 0)
                throw Marshal.GetExceptionForHR(result);
            string mime = Marshal.PtrToStringUni(mimeout);
            Marshal.FreeCoTaskMem(mimeout);
            return mime;
        }


...
Рейтинг: 0 / 0
29.07.2016, 13:50
    #39282744
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
Cat2NechtoКод рабочий.

Вы хотите сказать, что это компилируется?
Nechto
Код: c#
1.
2.
3.
4.
5.
6.
7.
switch (mimetypeOfFile)
               {
                    case "application/pdf": // .pdf
                    case "application/octet-stream": // .doc
                    case "application/x-zip-compressed": // .docx
                    case "application/x-zip-compressed": // .xlsx
               }



Это место для наглядности
...
Рейтинг: 0 / 0
29.07.2016, 13:54
    #39282749
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
Где-то в степиNechto,
ну а запилить с http://www.pinvoke.net/default.aspx/urlmon.findmimefromdata
не судьба?
два копипаста

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
  [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
        static extern int FindMimeFromData(IntPtr pBC,
                [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
               [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)]
        byte[] pBuffer,
                int cbSize,
                   [MarshalAs(UnmanagedType.LPWStr)]  string pwzMimeProposed,
                int dwMimeFlags,
                out IntPtr ppwzMimeOut,
                int dwReserved);

        public static string getMimeFromFile(string file)
        {
            IntPtr mimeout;
            if (!System.IO.File.Exists(file))
                throw new FileNotFoundException(file + " not found");

            int MaxContent = (int)new FileInfo(file).Length;
            if (MaxContent > 4096) MaxContent = 4096;
            FileStream fs = File.OpenRead(file);


            byte[] buf = new byte[MaxContent];
            fs.Read(buf, 0, MaxContent);
            fs.Close();
            int result = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, null, 0, out mimeout, 0);

            if (result != 0)
                throw Marshal.GetExceptionForHR(result);
            string mime = Marshal.PtrToStringUni(mimeout);
            Marshal.FreeCoTaskMem(mimeout);
            return mime;
        }




Чем мой пример отличается от этого?
...
Рейтинг: 0 / 0
29.07.2016, 13:56
    #39282754
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
NechtoЧем мой пример отличается от этого?
Ваш не работает
...
Рейтинг: 0 / 0
29.07.2016, 13:59
    #39282761
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
Cat2NechtoЧем мой пример отличается от этого?
Ваш не работает

Он работает, только почему-то выдает application/x-zip-compressed на файлы MSoffice 2010. Я поискал и нашел что дело возможно в архивации файла. Хотя данные в базу я сохраняю в исходном виде.
...
Рейтинг: 0 / 0
29.07.2016, 14:03
    #39282765
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
Потому что .docx и .xlsx это zip-архивы, можешь сменить расширение и открыть архиватором.

А mime type есть не для всех типов файлов. Например application/octet-stream это двоичный файл без указания формата, а не doc.

Надо не mime type смотреть, а сигнатуры искать, т.е. проверять содержимое файла на соответствие всем нужным форматам. С .docx и .xlsx это первые символы "PK" (сигнатура zip архива), затем извлекать оттуда [Content_Types].xml и смотреть его.
...
Рейтинг: 0 / 0
29.07.2016, 14:06
    #39282768
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
Dima TПотому что .docx и .xlsx это zip-архивы, можешь сменить расширение и открыть архиватором.

А mime type есть не для всех типов файлов. Например application/octet-stream это двоичный файл без указания формата, а не doc.

Надо не mime type смотреть, а сигнатуры искать, т.е. проверять содержимое файла на соответствие всем нужным форматам. С .docx и .xlsx это первые символы "PK" (сигнатура zip архива), затем извлекать оттуда [Content_Types].xml и смотреть его.

Наконец, то хоть один весомый ответ. В общем нужно реализовывать через context types
...
Рейтинг: 0 / 0
29.07.2016, 14:20
    #39282787
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
Dima TПотому что .docx и .xlsx это zip-архивы, можешь сменить расширение и открыть архиватором.

А mime type есть не для всех типов файлов. Например application/octet-stream это двоичный файл без указания формата, а не doc.

Надо не mime type смотреть, а сигнатуры искать, т.е. проверять содержимое файла на соответствие всем нужным форматам. С .docx и .xlsx это первые символы "PK" (сигнатура zip архива), затем извлекать оттуда [Content_Types].xml и смотреть его.

Все оказалось сложнее чем я думал. Можете хотя бы ссылку бросить на пример?
...
Рейтинг: 0 / 0
29.07.2016, 14:32
    #39282799
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
NechtoМожете хотя бы ссылку бросить на пример?
Ссылок нет. Да и не просто там все. Для каждого типа надо писать свой анализатор.
Может с другой стороны подойти - передавать расширение дополнительно, чтобы потом не мучится с его эвристическим угадыванием?
...
Рейтинг: 0 / 0
29.07.2016, 14:42
    #39282811
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
NechtoDima TПотому что .docx и .xlsx это zip-архивы, можешь сменить расширение и открыть архиватором.

А mime type есть не для всех типов файлов. Например application/octet-stream это двоичный файл без указания формата, а не doc.

Надо не mime type смотреть, а сигнатуры искать, т.е. проверять содержимое файла на соответствие всем нужным форматам. С .docx и .xlsx это первые символы "PK" (сигнатура zip архива), затем извлекать оттуда [Content_Types].xml и смотреть его.

Все оказалось сложнее чем я думал. Можете хотя бы ссылку бросить на пример?

Да похоже лучше так и сделать. Я просто считал что задача не сложная. Думал буду брать из базы файл (byte[]), и на лету определять его тип.
А оказалось сложнее.
...
Рейтинг: 0 / 0
29.07.2016, 16:18
    #39282951
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
c# Определить тип файла из byte[]
NechtoЯ просто считал что задача не сложная
она и не сложная.

сначала по сигнатурам, если zip архив оказался - чуток распаковать и определить что за офисный документ
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / c# Определить тип файла из byte[] / 13 сообщений из 13, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]