【CSharp】IniHelperWithGeneric

/*
 * INI文件说明:
 * INI是Initialization头三个字母的缩写;其后缀名也不一定是".ini"也可以是".cfg",".conf ”或者是".txt"
 * 
 * INI文件由节、键、值组成
 * 节
 *      [section]
 * 参数(键=值)
 *      name=value
 * 注解
 *      注解使用分号表示(;)。在分号后面的文字,直到该行结尾都全部为注解。
 *
 * NI文件的格式很简单,最基本的三个要素是:parameters,sections和comments。
 * 
 * 什么是parameters?
 *      INI所包含的最基本的“元素”就是parameter;每一个parameter都有一个name和一个value,
 *      name和value是由等号“=”隔开。name在等号的左边。
 *      如:
 *          name = value
 * 
 * 什么是sections?
 *      所有的parameters都是以sections为单位结合在一起的。所有的section名称都是独占一行,
 *      并且sections名字都被方括号包围着。在section声明后的所有parameters都是属于该section。
 *      对于一个section没有明显的结束标志符,一个section的开始就是上一个section的结束,
 *      或者是end of the file。Sections一般情况下不能被nested,当然特殊情况下也可以实现sections的嵌套。
 *      section如下所示:
 *          [section]
 * 
 * 什么是comments?
 *      在INI文件中注释语句是以分号“;”开始的。所有的所有的注释语句不管多长都是独占一行直到结束的。
 *      在分号和行结束符之间的所有内容都是被忽略的。
 *      注释实例如下:
 *          ;comments text
 */
namespace Steven
{
    public class IniHelper
    {
        #region Fields

        private string  m_FullName       = null;
        private int     m_ReadBufferSize =  512;

        #endregion

        #region Properties

        public string FullName
        {
            get { return this.m_FullName; }
        }

        public int ReadBufferSize
        {
            get
            {
                return this.m_ReadBufferSize;
            }
            set
            {
                this.m_ReadBufferSize = value;
            }
        }
        #endregion

        #region Constructors

        public IniHelper(string fullName = ".\\config.ini")
        {
            this.m_FullName = fullName;
        }

        #endregion

        #region Fuction Declare

        /// <summary>
        /// 写入INI文件
        /// </summary>
        /// <param name="section">节点名称,这个字串不区分大小写[如[TypeName]]</param>
        /// <param name="key">键,不区分大小写</param>
        /// <param name="val">值</param>
        /// <param name="filepath">INI文件的完整路径和文件名</param>
        /// <returns>非零表示成功,零表示失败</returns>
        [System.Runtime.InteropServices.DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filepath);


        /// <summary>
        /// 读取INI文件
        /// </summary>
        /// <param name="section">节点名称</param>
        /// <param name="key">键</param>
        /// <param name="defValue">读取异常的情况下的缺省值</param>
        /// <param name="retval">stringbulider对象</param>
        /// <param name="size">字节大小</param>
        /// <param name="filePath">INI文件的完整路径和文件名</param>
        /// <returns>复制到缓冲区的字节数量,其中不包括那些NULL中止字符。
        ///          若缓冲区size不够大,不能容下全部信息,就返回nSize-1
        ///          若section或key为NULL,则返回nSize-2</returns>
        [System.Runtime.InteropServices.DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string defValue,
                                                          System.Text.StringBuilder retval, int size, string filePath);

        #endregion

        #region Public Functions

        /// <summary>
        /// 将指定类型写入文件
        /// </summary>
        /// <param name="Section">节点名称</param>
        /// <param name="KeyName">参数名称</param>
        /// <param name="KeyValue">参数值</param>
        public void WriteIni<T>(string Section, string KeyName, T KeyValue)
        {
            long size = WritePrivateProfileString(Section, KeyName, KeyValue.ToString(), this.m_FullName);
            if (size == 0)
            {
                throw new System.Exception("Writting data to ini file is fail" + System.Environment.NewLine + this.m_FullName);
            }
        }

        /// <summary>
        /// 从文件中读出指定类型
        /// </summary>
        /// <param name="Section">节点名称</param>
        /// <param name="KeyName">参数名称</param>
        /// <param name="DefaultValue">默认值</param>
        /// <returns>读取值</returns>
        public T ReadIni<T>(string Section, string KeyName, T DefaultValue)
        {
            var stringBulder = new System.Text.StringBuilder(this.m_ReadBufferSize);
            long size = GetPrivateProfileString(Section, KeyName, DefaultValue.ToString(), stringBulder, this.m_ReadBufferSize, this.m_FullName);
            if (size == this.m_ReadBufferSize - 1)
            {
                throw new System.Exception("The read buffer is small, please change the buffer size");
            }
            else if (size == this.m_ReadBufferSize - 2)
            {
                throw new System.Exception("The section or key is not found, please check it");
            }

            System.Type tp = typeof(T);

            // 泛型Nullable判断,取其中的类型
            if (tp.IsGenericType)
            {
                tp = tp.GetGenericArguments()[0];
            }
            //string直接返回转换
            if (tp.Name.ToLower() == "string")
            {
                return (T)(object)stringBulder.ToString();
            }

            //反射获取TryParse方法
            var TryParse = tp.GetMethod("TryParse",
                                        System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static,
                                        System.Type.DefaultBinder,
                                        new System.Type[] { typeof(string), tp.MakeByRefType() },
                                        new System.Reflection.ParameterModifier[] { new System.Reflection.ParameterModifier(2) });
            var parameters = new object[] { stringBulder.ToString(), System.Activator.CreateInstance(tp) };
            bool success = (bool)TryParse.Invoke(null, parameters);
            //成功返回转换后的值,否则返回类型的默认值
            if (success)
            {
                return (T)parameters[1];
            }
            else
            {
                return default(T);
            }
        }

        #region Delete
        public void DeleteKey(string section, string key)
        {
            try
            {
                this.WriteIni<string>(section, key, null);
            }
            catch
            {
                throw;
            }
        }

        public void DeleteSection(string section)
        {
            try
            {
                this.WriteIni<string>(section, null, null);
            }
            catch
            {
                throw;
            }
        }

        public void DeleteAllSection()
        {
            try
            {
                this.WriteIni<string>(null, null, null);
            }
            catch
            {
                throw;
            }
        }
        #endregion

        #endregion
    }
}

OpenCV是一个开源的计算机视觉库,提供了丰富的图像处理和计算机视觉算法。而C#是一种面向对象的编程语言,它可以与OpenCV进行集成,以实现图像处理和计算机视觉应用。 在C#中使用OpenCV,你需要先安装OpenCV库,并将其与C#项目进行关联。可以通过NuGet包管理器来安装OpenCV的C#封装库,例如Emgu.CV。 一旦安装完成,你就可以在C#中使用OpenCV的功能了。你可以加载图像、进行图像处理、实现特征提取、目标检测等等。OpenCV提供了丰富的函数和类来支持这些功能,你可以根据具体需求选择适合的函数和类进行调用。 以下是一些常见的OpenCV在C#中的应用示例: 1. 加载和显示图像: ```csharp using Emgu.CV; using Emgu.CV.UI; Image<Bgr, byte> image = new Image<Bgr, byte>("image.jpg"); ImageViewer.Show(image, "Image"); ``` 2. 图像处理: ```csharp using Emgu.CV; using Emgu.CV.CvEnum; Image<Bgr, byte> image = new Image<Bgr, byte>("image.jpg"); Image<Gray, byte> grayImage = image.Convert<Gray, byte>(); CvInvoke.Canny(grayImage, grayImage, 100, 200); ``` 3. 特征提取: ```csharp using Emgu.CV; using Emgu.CV.CvEnum; using Emgu.CV.Features2D; using Emgu.CV.Structure; Image<Gray, byte> image = new Image<Gray, byte>("image.jpg"); SURFDetector surf = new SURFDetector(500, false); VectorOfKeyPoint keyPoints = surf.DetectKeyPointsRaw(image, null); ``` 4. 目标检测: ```csharp using Emgu.CV; using Emgu.CV.CvEnum; using Emgu.CV.Dnn; Net net = DnnInvoke.ReadNetFromDarknet("yolov3.cfg", "yolov3.weights"); Mat image = CvInvoke.Imread("image.jpg"); Mat blob = DnnInvoke.BlobFromImage(image, 1.0, new Size(416, 416), new MCvScalar(0, 0, 0), true, false); net.SetInput(blob); Mat result = net.Forward(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhy29563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值