zoukankan      html  css  js  c++  java
  • 原创 C# 正则表达式 读写 Ini 文件

    昨天遇到读ini文件的问题,我知道C#里没有提供相应的类,所有的.net配置都是xml方式存储的。

    读取ini文件,很多人直接google一把,然后添加dll引用。介绍的比较详细的,如: C#如何读写和创建INI文件 

    那么,如果不引用api呢? 我想到了正则表达式,分别读取section与key value,然后再匹配。刚好网上有一个类似的文章 用正则表达式读取INI文件

    看了下他的内容,然后再整理下思路,OK,我自己的Helper就出来了

    namespace goldli.Utility.Library
    {
        public interface IPosition
        {
            int Position { get; set; }     
        }
    
        public class IniKey : IPosition
        {
            public string Name { get; set; }
    
            public string Value { get; set; }
    
            public int Position { get; set; }
        }
    
        public class IniSection : Collection<IniKey>, IPosition
        {
            /// <summary>
            /// Section名称
            /// </summary>
            public string Name { get; set; }
    
            /// <summary>
            /// section在文件里位置,用于与KeyValue对比
            /// </summary>
            public int Position { get; set; }
    
            public IniKey Add(string keyName)
            {
                var result = Find(keyName);
                if (result == null)
                {
                    var key = new IniKey{Name = keyName};
                    Add(key);
                }
                return result;
            }
    
            public void Remove(string keyName)
            {
                var key = Find(keyName);
                if (key == null) return;
                Remove(key);
            }
    
            public override IniKey Find(object value)
            {
                var keyName = value as string;
                if(string.IsNullOrEmpty(keyName)) throw new ArgumentNullException("value");
                IniKey result = null;
                Lock();
                foreach (IniKey key in List)
                {
                    if (!Tools.IsSameString(key.Name, keyName)) continue;
                    result = key;
                    break;
                }
                UnLock();
                return result;
            }
    
            /// <summary>
            /// 判断一个key是否存在
            /// </summary>
            /// <param name="keyName"></param>
            /// <returns></returns>
            public bool KeyIsExist(string keyName)
            {
                return Find(keyName) != null;
            }
    
            /// <summary>
            /// 读取一个值
            /// </summary>
            /// <param name="keyName"></param>
            /// <returns></returns>
            public string ReadValue(string keyName)
            {
                var key = Find(keyName);
                return key != null ? key.Value : null;
            }
    
            /// <summary>
            /// 写入一个值
            /// </summary>
            /// <param name="keyName"></param>
            /// <param name="value"></param>
            public void WriteValue(string keyName,string value)
            {
                Add(keyName).Value = value;
            }
        }
    
        public class Sections :Collection<IniSection>
        {
            /// <summary>
            /// 查找
            /// </summary>
            /// <param name="value">Section.Name</param>
            /// <returns></returns>
            public override IniSection Find(object value)
            {
                var sectionName = value as string;
                if (string.IsNullOrEmpty(sectionName)) throw new ArgumentNullException("value");
                IniSection result = null;
                Lock();
                foreach (IniSection section in List)
                {
                    if (!Tools.IsSameString(section.Name,sectionName)) continue;
                    result = section;
                    break;
                }
                UnLock();
                return result;
            }
        }
    
        /// <summary>
        /// Ini文件读写类
        /// </summary>
        public class IniHelper
        {
            private IniKey[] _array;
            private int _arrarIndex;
    
            private const string ExpSection = "(?<=\[)\w+(?=\]\r)";
    
            /// <summary>
            /// 注:你要保证键值对中值不为空,即使是空字符串也不行
            /// </summary>
            private const string ExpKeyValue = "^(?<key>(?!;).+?)\s*=\s*(?<value>.*(?=\r))";
    
            //ini文件
            private readonly string _fileName;
    
            private void ExtractKeyValues(string data)
            {
                try
                {
                    var regexObj = new Regex(ExpKeyValue, RegexOptions.Multiline);
                    var mc = regexObj.Matches(data);
                    if (mc.Count > 0)
                    {
                        _array = new IniKey[mc.Count];
                        for (var i = 0; i < mc.Count; i++)
                        {
                            var m = mc[i].Groups;
                            var key = new IniKey { Name = m[1].Value, Value = m[2].Value, Position = m[1].Index };
                            _array[i] = key;
                        }
                    }
                    else
                    {
                        throw new RankException("error when regex key values.");
                    }
                }
                catch (Exception ex)
                {
                    Sections.Clear();
                    throw;
                }
            }
    
            private void ExtractSections(string data)
            {
                try
                {
                    var regexObj = new Regex(ExpSection);
                    var matchResults = regexObj.Match(data);
                    while (matchResults.Success)
                    {
                        var g = matchResults.Groups[0];
                        var section = new IniSection { Name = g.Value, Position = g.Index };
                        Sections.Add(section);
                        matchResults = matchResults.NextMatch();
                    }
                }
                catch (Exception ex)
                {
                    Sections.Clear();
                    throw;
                }
            }
    
            /// <summary>
            /// 根据起始位置查找keyvalue
            /// </summary>
            /// <param name="section"></param>
            /// <param name="next"></param>
            private void FillSection(IniSection section,int next)
            {
                for (var i = _arrarIndex; i < _array.Length; i++)
                {
                    var key = _array[i];
                    if ((section.Position < key.Position) && (key.Position < next))
                    {
                        section.Add(key);
                        _arrarIndex++;
                    }
                    else
                        break;
                }
            }
    
            private void FillSections()
            {
                _arrarIndex = 0;
                for (var i = 0; i < Sections.Count; i++)
                {
                    var section = Sections[i];
                    var next = int.MaxValue;
                    if ((i + 1) != Sections.Count)
                        next = Sections[i + 1].Position;
                    FillSection(section,next);
                }
                Array.Clear(_array,0,_array.Length);
            }
    
            public IniHelper(string fileName)
            {
                _fileName = fileName;
                Sections =new Sections();
            }
    
            /// <summary>
            /// 文件编码
            /// </summary>
            public Encoding FileEncoding { get; set; }
    
            /// <summary>
            /// 加载文件
            /// </summary>
            public void Load()
            {
                var data = FileReadWriteHelper.Read(_fileName, FileEncoding.WebName);
                if (string.IsNullOrEmpty(data)) throw new FileLoadException(_fileName);
                ExtractSections(data);
                ExtractKeyValues(data);
                FillSections();
            }
    
            /// <summary>
            /// 保存文件
            /// </summary>
            public void Save(string fileName)
            {
                var iniBuilder = new StringBuilder();
                foreach (IniSection section in Sections)
                {
                    var aSection = string.Format("[{0}]
    ", section.Name);
                    iniBuilder.Append(aSection);
                    foreach (IniKey key in section)
                    {
                        var aKeyValue = string.Format("{0}={1}
    ", key.Name, key.Value);
                        iniBuilder.Append(aKeyValue);
                    }
                    iniBuilder.Append(Environment.NewLine);
                }
                FileReadWriteHelper.Write(fileName, iniBuilder.ToString(), FileEncoding.WebName);
            }
    
            public IniSection Add(string sectionName)
            {
                var section = Sections.Find(sectionName);
                if (section == null)
                {
                    section = new IniSection {Name = sectionName};
                    Sections.Add(section);
                }
                return section;
            }
    
            public void Add(IniSection section)
            {
                var tmp = Sections.Find(section.Name);    
                if (tmp == null) 
                    Sections.Add(section);
            }
    
            public void Remove(string sectionName)
            {
                var section = Sections.Find(sectionName);
                if (section == null) return;
                Sections.Remove(section);
            }
    
            public void Remove(IniSection section)
            {
                var tmp = Sections.Find(section.Name);
                if (tmp == null) return;
                Sections.Remove(section);
            }
    
            public Sections Sections { get; private set; }
        }
    }
    

     使用示例

      var ini = new IniHelper(@"i:spring.ini");
      ini.FileEncoding = Encoding.ASCII;
      ini.Load();
      textBox1.Clear();
      foreach (IniSection section in ini.Sections)
      {
          extBox1.AppendText("[" + section.Name +"]
    ");
          foreach (IniKey key in section)
          {
              textBox1.AppendText(key.Name + " = " + key.Value + "
    ");    
          }
      }
    

     哈哈,其实挺简单的。主要的问题是把正则写正确。

  • 相关阅读:
    jMeter 里 CSV Data Set Config Sharing Mode 的含义详解
    如何使用 jMeter Parallel Controller
    使用 Chrome 开发者工具 coverage 功能分析 web 应用的渲染阻止资源的执行分布情况
    使用 Chrome 开发者工具的 lighthouse 功能分析 web 应用的性能问题
    关于 SAP 电商云首页加载时触发的 OCC API 请求
    SAP UI5 确保控件 id 全局唯一的实现方法
    SAP 电商云 Accelerator 和 Spartacus UI 的工作机制差异
    介绍一个好用的能让网页变成黑色背景的护眼 Chrome 扩展应用
    Chrome 开发者工具 performance 标签页的用法
    Client Side Cache 和 Server Side Cache 的区别
  • 原文地址:https://www.cnblogs.com/goldli/p/3183550.html
Copyright © 2011-2022 走看看