امتدادات الملفات وأنواع مايم في.NET




asp.net content-type (5)

ليس لدي مجموعة واسعة من نوع مايم للتعامل معها في تطبيقات بلدي، لذلك أنا باستخدام جدول بحث مثلك.

لم تكن فكرتك سيئة على الإطلاق. تحتاج فقط أن يكون وسيلة سهلة للحفاظ على وتحديث البحث.

أريد الحصول على نوع محتوى مايم من امتداد معين (ويفضل دون الوصول إلى الملف الفعلي). لقد رأيت بعض الأسئلة حول هذا، والأساليب المذكورة لأداء هذا يمكن أن تستأنف في:

  1. استخدام معلومات التسجيل .
  2. استخدام فيندميمفرومداتا urlmon.dll .
  3. استخدام معلومات إيس .
  4. لفة الخاص بك وظيفة مايم رسم الخرائط. استنادا إلى هذا الجدول ، على سبيل المثال.

لقد تم استخدام no.1 لبعض الوقت ولكن أدركت أن المعلومات التي يقدمها السجل ليست متسقة ويعتمد على البرنامج المثبت على الجهاز. لا تستخدم بعض الإضافات، مثل .zip، لتحديد نوع المحتوى.

الحل NO.2 يجبرني أن يكون الملف على القرص من أجل قراءة البايتات الأولى، وهو شيء بطيء ولكن قد تحصل على نتائج جيدة.

وتستند الطريقة الثالثة على خدمات الدليل وجميع هذه الأشياء، وهو شيء أنا لا أحب كثيرا لأن لدي لإضافة مراجع كوم وأنا لست متأكدا من أنه يتفق بين IIS6 و IIS7. أيضا، أنا لا أعرف أداء هذه الطريقة.

وأخيرا، لم أكن أريد أن استخدام بلدي الجدول ولكن في النهاية يبدو الخيار الأفضل إذا أريد أداء لائق واتساق النتائج بين المنصات (حتى مونو).

هل تعتقد أن هناك خيارا أفضل من استخدام الجدول الخاص بي أو واحدة من الطرق الأخرى المذكورة هي أفضل؟ ما هي تجربتك؟


لقد جمعت كل هذه النهج في ليبوي فائدة، باستثناء ربما NO.3. راجع للشغل، NO.2 (urlmon.dll) لا يتطلب ملف ثابت، فإنه يأخذ ببساطة بعض وحدات البايت بغض النظر عن المكان الذي جاءوا منه. إليك فئتي الحالية

namespace Components
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Xml.Serialization;
    using Microsoft.Win32;

    public sealed class MimeExtensionHelper
    {
        private MimeExtensionHelper() { }

        /// <summary>Finds extension associated with specified mime type</summary>
        /// <param name="mimeType">mime type you search extension for, e.g.: "application/octet-stream"</param>
        /// <returns>most used extension, associated with provided type, e.g.: ".bin"</returns>
        public static string FindExtension(string mimeType)
        {
            return ExtensionTypes.GetExtension(mimeType);
        }

        /// <summary>Finds mime type using provided extension and/or file's binary content.</summary>
        /// <param name="file">Full file path</param>
        /// <param name="verifyFromContent">Should the file's content be examined to verify founded value.</param>
        /// <returns>mime type of file, e.g.: "application/octet-stream"</returns>
        public static string FindMime(string file,bool verifyFromContent)
        {
            string extension = Path.GetExtension(file);
            string mimeType = string.Empty;
            try
            {
                if (!String.IsNullOrEmpty(extension))
                    mimeType = ExtensionTypes.GetMimeType(extension);
                if (verifyFromContent
                    || (String.IsNullOrEmpty(mimeType) && File.Exists(file)))
                    mimeType = FindMimeByContent(file,mimeType);
            }
            catch { }
            return (mimeType ?? string.Empty).Trim();//"application/octet-stream"
        }

        /// <summary>Finds mime type for file using it's binary data.</summary>
        /// <param name="file">Full path to file.</param>
        /// <param name="proposedType">Optional. Expected file's type.</param>
        /// <returns>mime type, e.g.: "application/octet-stream"</returns>
        public static string FindMimeByContent(string file
            ,string proposedType)
        {
            FileInfo fi = new FileInfo(file);
            if (!fi.Exists)
                throw new FileNotFoundException(file);
            byte[] buf = new byte[Math.Min(4096L,fi.Length)];
            using (FileStream fs = File.OpenRead(file))
                fs.Read(buf,0,buf.Length);
            return FindMimeByData(buf,proposedType);
        }

        /// <summary>Finds mime type for binary data.</summary>
        /// <param name="dataBytes">Binary data to examine.</param>
        /// <param name="mimeProposed">Optional. Expected mime type.</param>
        /// <returns>mime type, e.g.: "application/octet-stream"</returns>
        public static string FindMimeByData(byte[] dataBytes,string mimeProposed)
        {
            if (dataBytes == null || dataBytes.Length == 0)
                throw new ArgumentNullException("dataBytes");
            string mimeRet = String.Empty;
            IntPtr outPtr = IntPtr.Zero;
            if (!String.IsNullOrEmpty(mimeProposed))
                mimeRet = mimeProposed;
            int result = FindMimeFromData(IntPtr.Zero
                ,null
                ,dataBytes
                ,dataBytes.Length
                ,String.IsNullOrEmpty(mimeProposed) ? null : mimeProposed
                ,0
                ,out outPtr
                ,0);
            if (result != 0)
                throw Marshal.GetExceptionForHR(result);
            if (outPtr != null && outPtr != IntPtr.Zero)
            {
                mimeRet = Marshal.PtrToStringUni(outPtr);
                Marshal.FreeCoTaskMem(outPtr);
            }
            return mimeRet;
        }

        [DllImport("urlmon.dll"
            ,CharSet = CharSet.Unicode
            ,ExactSpelling = true
            ,SetLastError = true)]
        static extern Int32 FindMimeFromData(IntPtr pBC
            ,[MarshalAs(UnmanagedType.LPWStr)] String pwzUrl
            ,[MarshalAs(UnmanagedType.LPArray,ArraySubType = UnmanagedType.I1,SizeParamIndex = 3)] Byte[] pBuffer
            ,Int32 cbSize
            ,[MarshalAs(UnmanagedType.LPWStr)] String pwzMimeProposed
            ,Int32 dwMimeFlags
            ,out IntPtr ppwzMimeOut
            ,Int32 dwReserved);

        private static MimeTypeCollection _extensionTypes = null;
        private static MimeTypeCollection ExtensionTypes
        {
            get
            {
                if (_extensionTypes == null)
                    _extensionTypes = new MimeTypeCollection();
                return _extensionTypes;
            }
        }

        [Serializable]
        [XmlRoot(ElementName = "mimeTypes")]
        private class MimeTypeCollection : List<MimeTypeCollection.mimeTypeInfo>
        {
            private SortedList<string,string> _extensions;
            private SortedList<string,List<string>> _mimes;

            private void Init()
            {
                if (_extensions == null || _mimes == null
                    || _extensions.Count == 0 || _mimes.Count == 0)
                {
                    _extensions = new SortedList<string,string>(StringComparer.OrdinalIgnoreCase);
                    _mimes = new SortedList<string,List<string>>(StringComparer.OrdinalIgnoreCase);
                    foreach (var mime in this)
                    {
                        _mimes.Add(mime.MimeType,new List<string>(mime.Extensions));
                        foreach (string ext in mime.Extensions)
                            if (!_extensions.ContainsKey(ext))
                                _extensions.Add(ext,mime.MimeType);
                    }
                }
            }

            public String GetExtension(string type)
            {
                Init();
                return _mimes.ContainsKey(type) ? _mimes[type][0] : string.Empty;
            }

            public String GetMimeType(string extension)
            {
                Init();
                return _extensions.ContainsKey(extension) ? _extensions[extension] : string.Empty;
            }

        public MimeTypeCollection()
        {
            this.Add(new mimeTypeInfo("application/applixware",new List<string>(new[] { ".aw" })));
            this.Add(new mimeTypeInfo("application/atom+xml",new List<string>(new[] { ".atom" })));
            // ... Whole list from apache's site
            this.Add(new mimeTypeInfo("x-x509-ca-cert",new List<string>(new[] { ".cer" })));
            try
            {
                using (RegistryKey classesRoot = Registry.ClassesRoot)
                using (RegistryKey typeKey = classesRoot.OpenSubKey(@"MIME\Database\Content Type"))
                {
                    string[] subKeyNames = typeKey.GetSubKeyNames();
                    string extension = string.Empty;
                    foreach (string keyname in subKeyNames)
                    {
                        string trimmed = (keyname ?? string.Empty).Trim();
                        if (string.IsNullOrEmpty(trimmed))
                            continue;
                        if (!String.IsNullOrEmpty(GetExtension(trimmed)))
                            continue;
                        string subKey = "MIME\\Database\\Content Type\\" + trimmed;
                        using (RegistryKey curKey = classesRoot.OpenSubKey(subKey))
                        {
                            extension = (curKey.GetValue("Extension") as string ?? string.Empty).Trim();
                            if (extension.Length > 0)
                                this.Add(new mimeTypeInfo(trimmed
                                    ,new List<string>(new[] { extension })));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string s = ex.ToString();
            }
        }

        [Serializable]
        public class mimeTypeInfo
        {
            [XmlAttribute(AttributeName = "mimeType")]
            public String MimeType { get; set; }

            [XmlElement("extension")]
            public List<String> Extensions { get; set; }

            public mimeTypeInfo(string mimeType,List<string> extensions)
            {
                MimeType = mimeType;
                Extensions = extensions;
            }

            public mimeTypeInfo() { }
        }
    }
}

}


ووجدت أيضا أن طريقة إينيت () سيتم استدعاؤها ولن يتم تهيئة أعضاء _extensions و _mime بشكل كامل لذلك أنا غيرت لقراءة، وأفضل طريقة هي إزالة المكالمة جيتكستنسيون في منشئ من ميمتيبيكولكتيون:

        public MimeTypeCollection()
        {
            this.Add(new mimeTypeInfo("application/applixware", new List<string>(new[] { ".aw" })));
            this.Add(new mimeTypeInfo("application/atom+xml", new List<string>(new[] { ".atom" })));
            // ... Whole list from apache's site
            this.Add(new mimeTypeInfo("x-x509-ca-cert", new List<string>(new[] { ".cer" })));
            try
            {
                using (RegistryKey classesRoot = Registry.ClassesRoot)
                using (RegistryKey typeKey = classesRoot.OpenSubKey(@"MIME\Database\Content Type"))
                {
                    string[] subKeyNames = typeKey.GetSubKeyNames();
                    string extension = string.Empty;
                    foreach (string keyname in subKeyNames)
                    {
                        string trimmed = (keyname ?? string.Empty).Trim();
                        if (string.IsNullOrEmpty(trimmed))
                            continue;
                        if (this.Exists(mime => mime.MimeType == trimmed))
                            continue;
                        //if (!String.IsNullOrEmpty(GetExtension(trimmed)))
                        //  continue;
                        string subKey = "MIME\\Database\\Content Type\\" + trimmed;
                        using (RegistryKey curKey = classesRoot.OpenSubKey(subKey))
                        {
                            extension = (curKey.GetValue("Extension") as string ?? string.Empty).Trim();
                            if (extension.Length > 0)
                                this.Add(new mimeTypeInfo(trimmed
                                        , new List<string>(new[] { extension })));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string s = ex.ToString();
            }
        }


ذلك يعتمد ما تحتاجه نوع مايم ل. بشكل عام، بالنسبة للخدمات (تطبيقات الويب، خدمة الويب، وما إلى ذلك)، فإنه من المستحسن عدم استخدام قائمة مايم التي تعتمد على إعدادات نظام التشغيل، أو فقط كإرجاع إذا لم تتمكن من العثور على معلومات مايم خلاف ذلك.

وأعتقد أن هذا هو أيضا السبب في اختيار مس لوضع أنواع مايم ثابتة في فئة System.Web.MimeMapping لها (للأسف انها الداخلية، لأي سبب من الأسباب).

تصحيح:

ورابر (<= .NET 3.5)

public static class MimeExtensionHelper
{
    static object locker = new object();
    static object mimeMapping;
    static MethodInfo getMimeMappingMethodInfo;

    static MimeExtensionHelper()
    {
        Type mimeMappingType = Assembly.GetAssembly(typeof(HttpRuntime)).GetType("System.Web.MimeMapping");
        if (mimeMappingType == null)
            throw new SystemException("Couldnt find MimeMapping type");
        ConstructorInfo constructorInfo = mimeMappingType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
        if (constructorInfo == null)
            throw new SystemException("Couldnt find default constructor for MimeMapping");
        mimeMapping = constructorInfo.Invoke(null);
        if (mimeMapping == null)
            throw new SystemException("Couldnt find MimeMapping");
        getMimeMappingMethodInfo = mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic);
        if (getMimeMappingMethodInfo == null)
            throw new SystemException("Couldnt find GetMimeMapping method");
        if (getMimeMappingMethodInfo.ReturnType != typeof(string))
            throw new SystemException("GetMimeMapping method has invalid return type");
        if (getMimeMappingMethodInfo.GetParameters().Length != 1 && getMimeMappingMethodInfo.GetParameters()[0].ParameterType != typeof(string))
            throw new SystemException("GetMimeMapping method has invalid parameters");
    }
    public static string GetMimeType(string filename)
    {
        lock (locker)
            return (string)getMimeMappingMethodInfo.Invoke(mimeMapping, new object[] { filename });
    }
}

ورابر (.NET 4.0)

public static class MimeExtensionHelper
    {
        static object locker = new object();
        static object mimeMapping;
        static MethodInfo getMimeMappingMethodInfo;

        static MimeExtensionHelper()
        {
            Type mimeMappingType = Assembly.GetAssembly(typeof(HttpRuntime)).GetType("System.Web.MimeMapping");
            if (mimeMappingType == null)
                throw new SystemException("Couldnt find MimeMapping type");            
            getMimeMappingMethodInfo = mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
            if (getMimeMappingMethodInfo == null)
                throw new SystemException("Couldnt find GetMimeMapping method");
            if (getMimeMappingMethodInfo.ReturnType != typeof(string))
                throw new SystemException("GetMimeMapping method has invalid return type");
            if (getMimeMappingMethodInfo.GetParameters().Length != 1 && getMimeMappingMethodInfo.GetParameters()[0].ParameterType != typeof(string))
                throw new SystemException("GetMimeMapping method has invalid parameters");
        }
        public static string GetMimeType(string filename)
        {
            lock (locker)
                return (string)getMimeMappingMethodInfo.Invoke(mimeMapping, new object[] { filename });
        }
    }

.NET 4.5+

لا المجمع المطلوبة، استدعاء الأسلوب العام System.Web.MimeMapping.GetMimeMapping مباشرة.





file-extension