Страницы

Поиск по вопросам

среда, 26 февраля 2020 г.

Проверка расширения файла перед сохранением

#c_sharp


Качаю файл с удаленного хоста. Сайт content/type отдаёт application/octet stream.
Можно ли предварительно узнать какой файл скачивается? По урл невозможно определить

HttpWebRequest req = (HttpWebRequest) WebRequest.Create(url+"download");
 req.Method = "GET";
 var httpResponse = (HttpWebResponse) req.GetResponse();
 Stream httpResponseStream = httpResponse.GetResponseStream();

    


Ответы

Ответ 1



Вариант 1: Вы можете например использовать функцию FindMimeFromData() живущую в Urlmon.dll. Вот один из пeримеров как ее подключить в C# : 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; } Подробнее на http://www.pinvoke.net/default.aspx/urlmon/findmimefromdata.html Вариант 2: Использовать что-то готовое для этих целей, например https://github.com/Muraad/Mime-Detective Вариант 3: Написать парсер самому, с учётом сигнатуры заголовков различных файлов, например, как часть, определения типов сигнатур наиболее распространенных файлов: public class MyMimeType { private static readonly byte[] BMP = { 66, 77 }; private static readonly byte[] DOC = { 208, 207, 17, 224, 161, 177, 26, 225 }; private static readonly byte[] EXE_DLL = { 77, 90 }; private static readonly byte[] GIF = { 71, 73, 70, 56 }; private static readonly byte[] ICO = { 0, 0, 1, 0 }; private static readonly byte[] JPG = { 255, 216, 255 }; private static readonly byte[] MP3 = { 255, 251, 48 }; private static readonly byte[] OGG = { 79, 103, 103, 83, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 }; private static readonly byte[] PDF = { 37, 80, 68, 70, 45, 49, 46 }; private static readonly byte[] PNG = { 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82 }; private static readonly byte[] RAR = { 82, 97, 114, 33, 26, 7, 0 }; private static readonly byte[] SWF = { 70, 87, 83 }; private static readonly byte[] TIFF = { 73, 73, 42, 0 }; private static readonly byte[] TORRENT = { 100, 56, 58, 97, 110, 110, 111, 117, 110, 99, 101 }; private static readonly byte[] TTF = { 0, 1, 0, 0, 0 }; private static readonly byte[] WAV_AVI = { 82, 73, 70, 70 }; private static readonly byte[] WMV_WMA = { 48, 38, 178, 117, 142, 102, 207, 17, 166, 217, 0, 170, 0, 98, 206, 108 }; private static readonly byte[] ZIP_DOCX = { 80, 75, 3, 4 }; Ну и самое интересное, как получить часть файла, для анализа типа файла одним из приведенных выше способом. Надо получать файл не полностью, а отправляя заголовок Range в http запросе, подробнее об этой технологии тут https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests Вот пример кода как это организовать на C#: int size = 256; using (var httpclient = new HttpClient()) { httpclient.DefaultRequestHeaders.Range = new RangeHeaderValue(0, size); var response = await httpclient.GetAsync(url,HttpCompletionOption.ResponseHeadersRead); using (var stream = await response.Content.ReadAsStreamAsync()) { var bytes = new byte[size]; var bytesread = stream.Read(bytes, 0, bytes.Length); stream.Close(); } }

Комментариев нет:

Отправить комментарий