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 + "
    ");    
          }
      }
    

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

  • 相关阅读:
    fenby C语言P21
    fenby C语言 P20
    fenby C语言 P19
    fenby C语言 P18
    fenby C语言 P17
    fenby C语言 P16
    fenby C语言 P15
    fenby C语言 P14
    Python学习之路:subprocess模块和面向对象
    Python学习之路:XML模块
  • 原文地址:https://www.cnblogs.com/goldli/p/3183550.html
Copyright © 2011-2022 走看看