header#gh-head { background-color: blue; }

hi

using DataEngine.Common.LogManager;

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Reflection;

using System.Text;

using Utility;

namespace DataEngine.Common.Util

{

   public class CgFileHelper

   {

       /// <summary>

       /// INI 文件绝对路径

       /// </summary>

       public string Path { get; protected set; }

       public Dictionary<string, Dictionary<string, string>> MapSectionName2Contents { get; private set; }

       private Dictionary<string, List<string>> m_mapSectionName2LstComment = new Dictionary<string, List<string>>();

       protected CgFileHelper(string filePath , Encoding encoding = null)

       {

           try

           {

               Path = filePath;

               ReadValues(filePath, out Dictionary<string, Dictionary<string, string>> mapSectionName2Contents, out Dictionary<string, List<string>> mapSectionName2LstComment, encoding);

               MapSectionName2Contents = mapSectionName2Contents;

               m_mapSectionName2LstComment = mapSectionName2LstComment;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

       }

       

       public static void ReadValues(string filePath,out Dictionary<string, Dictionary<string, string>> mapSectionName2Contents,out Dictionary<string, List<string>> mapSectionName2LstComment, Encoding encoding = null)

       {

           mapSectionName2Contents = new Dictionary<string, Dictionary<string, string>>();

           mapSectionName2LstComment = new Dictionary<string, List<string>>();

           try

           {

               if (encoding == null)

                   encoding = Encoding.Default;

               var lstLine = File.ReadAllLines(filePath, encoding).Select(a => a.Trim()).ToList();

               var lstLineContentDst = new List<string>();

               foreach (var item in lstLine)

               {

                   if (string.IsNullOrWhiteSpace(item))

                   {

                       continue;

                   }

                   if (item[0] == ';' || item[0] == ';' || item == "[]")

                   {

                       continue;

                   }

                   if (item.StartsWith("[") && !item.EndsWith("]"))

                   {

                       continue;

                   }

                   lstLineContentDst.Add(item);

               }

               string sectionName = "";

               foreach (var line in lstLineContentDst)

               {

                   if (line[0] == '[' && line[line.Length - 1] == ']')

                   {

                       sectionName = line.Substring(1, line.Length - 2);

                       if (mapSectionName2Contents.ContainsKey(sectionName))

                       {

                           PromptFacade.Instance.UpdatePromptWithToastBox(PromptType.Error, "文件读取失败,因为段名重复,文件名:" + filePath + ",段:" + sectionName);

                           return;

                       }

                       mapSectionName2Contents.Add(sectionName, new Dictionary<string, string>());

                   }

                   else if (line.Contains("="))

                   {

                       string key = line.Split('=')[0].Trim();

                       if(!mapSectionName2Contents.ContainsKey(sectionName))

                       {

                           PromptFacade.Instance.UpdatePromptWithToastBox(PromptType.Error, "文件读取失败,因为段名不存在:" + filePath + ",段:" + sectionName);

                       }

                       if (mapSectionName2Contents[sectionName].ContainsKey(key))

                       {

                           continue;//T4配置可能有重复的key

                       }

                       string value = line.Substring(line.IndexOf('=') + 1).Trim();

                       mapSectionName2Contents[sectionName].Add(key, value);

                   }

               }

               var lstLineComment = new List<string>();

               foreach (var item in lstLine)

               {

                   if (string.IsNullOrWhiteSpace(item) || item == "[]")

                   {

                       continue;

                   }

                   if (item.StartsWith(";") || item.StartsWith(";"))

                   {

                       lstLineComment.Add(item);

                   }

                   else if (item.StartsWith("[") && item.EndsWith("]")&&lstLineComment.Count>0)

                   {

                       string sSectionName = item.Substring(1, item.Length - 2);

                       mapSectionName2LstComment.Add(sSectionName, new List<string>(lstLineComment));

                       lstLineComment.Clear();

                   }

               }

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

       }

       /// <summary>

       /// 获取指定文件的INIFILE对象

       /// </summary>

       /// <param name="filePath">文件路径</param>

       /// <param name="bClearContentIfFileExisted">如果文件已存在,清空内容</param>

       /// <returns>INIFiled对象</returns>

       public static CgFileHelper CreateFromFile(string filePath,bool bClearContentIfFileExisted=false, Encoding encoding = null)

       {

           try

           {

               if (!string.IsNullOrEmpty(filePath))

               {

                   int index = filePath.LastIndexOf('\\');

                   string dirPath = filePath.Substring(0, index);

                   if (!Directory.Exists(dirPath))

                   {

                       Directory.CreateDirectory(dirPath);

                   }

                   if (!File.Exists(filePath))

                   {

                       FileStream newFile = File.Create(filePath);

                       newFile.Close();

                   }

                   else if(bClearContentIfFileExisted)

                   {

                       File.WriteAllLines(filePath, new string[0]);

                   }

                   return new CgFileHelper(filePath, encoding);

               }

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return null;

       }

       #region 读

       public List<string> ReadAllSectionNames()

       {

           try

           {

               return new List<string>(MapSectionName2Contents.Keys);

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return null;

       }

       public List<string> ReadListValues(string sectionName, string numStr)

       {

           List<string> list = new List<string>();

           try

           {

               string strNum = ReadStringValue(sectionName, numStr);

               strNum = strNum.Replace(';', ' ').Replace(';',' ').Trim();

               int num;

               if (!int.TryParse(strNum, out num))

               {

                   return list;

               }

               var mapKey2Value = MapSectionName2Contents[sectionName];

               for (int index = 1; index <= num; index++)

               {

                   string value = mapKey2Value[index.ToString()];

                   list.Add(value);

               }

           }

           catch (Exception ex) {

               PromptFacade.Instance.UpdatePromptWithToastBox(PromptType.Error, "文件读取失败,文件名:" + Path + ",段:" + sectionName);

               ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return list;

       }

       public List<string> ReadList(string sectionName)

       {

           List<string> list = new List<string>();

           do

           {

               if (MapSectionName2Contents == null)

                   break;

               if (!MapSectionName2Contents.TryGetValue(sectionName, out Dictionary<string, string> dicVal))

                   break;

               int i = 1;

               while (true)

               {

                   if (dicVal.TryGetValue(i++.ToString(), out string val))

                   {

                       list.Add(val);

                   }

                   else

                   {

                       break;

                   }

               }

           } while (false);

           return list;

       }

       public string ReadStringValue(string sectionName, string key)

       {

           string value = "";

           try

           {

               if (MapSectionName2Contents.ContainsKey(sectionName) && MapSectionName2Contents[sectionName].ContainsKey(key))

               {

                   value = MapSectionName2Contents[sectionName][key];

               }

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return value;

       }

       public bool ReadStringValuePromptError(string sectionName, int key,out string value)

       {

           value = "";

           try

           {

               if (MapSectionName2Contents.ContainsKey(sectionName))

               {

                   if (!MapSectionName2Contents[sectionName].ContainsKey(key.ToString()))

                   {

                       string fileName = Path.Split('\\').Last();

                       PromptFacade.Instance.UpdatePromptWithToastBox(PromptType.Error, $"{fileName}:段:{sectionName} 下存在错误!");

                       if (MapSectionName2Contents[sectionName].Any(a => int.TryParse(a.Key, out int int_Key) && int_Key > key))

                       {

                           PromptFacade.Instance.UpdatePrompt(PromptType.Error, $"{fileName}:段:{sectionName} 下 序号不连续 找不到序号:{key}!");

                       }

                       return false;

                   }

                   value = MapSectionName2Contents[sectionName][key.ToString()];

               }

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public int ReadIntValue(string sSectionName,string sKey,bool bWithMsgBox=true,int nDefaultValue=-1)

       {

           try

           {

               int num;

               string value = ReadStringValue(sSectionName, sKey);

               if (int.TryParse(value, out num))

               {

                   return num;

               }

               else if(bWithMsgBox)

               {

                   string err = string.Format("文件{0}:段[{1}]键{2}的值{3}不是整数", Path, sSectionName, sKey, value);

                   PromptFacade.Instance.UpdatePromptWithToastBox(PromptType.Error, err);

               }

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return nDefaultValue;

       }

       public bool ReadBoolValue(string sectionName, string key, bool withMsgBox = true, bool defaultValue = false)

       {

           string val = ReadStringValue(sectionName, key);

           bool ret = defaultValue;

           if (!string.IsNullOrWhiteSpace(val) && bool.TryParse(val, out ret))

           {

           }

           else

           {

               ret = defaultValue;

               if (withMsgBox)

               {

                   string err = string.Format("文件{0}:段[{1}]键{2}的值{3}不是布尔值", Path, sectionName, key, val);

                   PromptFacade.Instance.UpdatePromptWithToastBox(PromptType.Error, err);

               }

           }

           return ret;

       }

       public Dictionary<string, string> ReadKeyValues(string sectionName)

       {

           var mapKey2Value = new Dictionary<string, string>();

           try

           {

               if (MapSectionName2Contents.ContainsKey(sectionName))

               {

                   mapKey2Value = new Dictionary<string, string>(MapSectionName2Contents[sectionName]);

               }

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return mapKey2Value;

       }

       /// <summary>

       /// 获取某一个section下根据个数获取所有的数据字典

       /// </summary>

       /// <param name="section"></param>

       /// <param name="numStr">个数的称谓,比如总数, 个数,统计数目等</param>

       /// <returns></returns>

       public Dictionary<string, string> ReadDicValues(string section, string numStr)

       {

           Dictionary<string, string> dic = new Dictionary<string, string>();

           try

           {

               if (!ReadAllSectionNames().Contains(section))

               {

                   return dic;

               }

               int num = 0;

               string strNum = ReadStringValue(section, numStr);

               if (string.IsNullOrWhiteSpace(strNum) || !int.TryParse(strNum, out num))

               {

                   return null;

               }

               for (int index = 1; index <= num; index++)

               {

                   string value = ReadStringValue(section, index.ToString()).Trim();

                   dic.Add(index.ToString(), value);

               }

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return dic;

       }

       public bool CopyContents(Dictionary<string,Dictionary<string,string>> mapSectionName2Contents)

       {

           try

           {

               MapSectionName2Contents = mapSectionName2Contents;

               m_mapSectionName2LstComment = new Dictionary<string, List<string>>();

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public List<string> ReadDiscontinousList(string sectionName)

       {

           List<string> list = new List<string>();

           do

           {

               if (MapSectionName2Contents == null)

                   break;

               if (!MapSectionName2Contents.TryGetValue(sectionName, out Dictionary<string, string> dicVal))

                   break;

               foreach(var item in dicVal)

               {

                   if(!int.TryParse(item.Key, out int val))

                   {

                       continue;

                   }

                   else

                   {

                       list.Add(item.Value);

                   }

               }

           } while (false);

           return list;

       }

       #endregion

       #region 写

       public bool WriteValue(object sectionName, object key, object value)

       {

           return WriteValue(MapSectionName2Contents, sectionName, key, value);

       }

       public void RemoveValue(object sectionName, object key)

       {

           if(MapSectionName2Contents.TryGetValue(sectionName.ToString(), out Dictionary<string, string> val))

           {

               val.Remove(key.ToString());

           }

       }

       public static bool WriteValue(Dictionary<string, Dictionary<string, string>> mapSectionName2Contents, object sectionName, object key, object value)

       {

           try

           {

               string sSectionName = sectionName.ToString();

               if (!mapSectionName2Contents.ContainsKey(sSectionName))

               {

                   mapSectionName2Contents.Add(sSectionName, new Dictionary<string, string>());

               }

               bool bRet = WriteValue(mapSectionName2Contents[sSectionName], key, value);

               return bRet;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public static bool WriteValue(Dictionary<string, string> mapContents, object key, object value)

       {

           try

           {

               if (key == null || value == null)//只是占个位置

               {

                   return true;

               }

               string sKey = key.ToString();

               string sValue = value.ToString();

               if (!mapContents.ContainsKey(sKey))

               {

                   mapContents.Add(sKey, sValue);

               }

               else

               {

                   mapContents[sKey] = sValue;

               }

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public bool WriteListValue(object section, List<string> lstValue, string sNumKeyWrite = null, string keyPrefix = null)

       {

           try

           {

               bool bRet = WriteListValue(MapSectionName2Contents, section, lstValue, sNumKeyWrite, keyPrefix);

               return bRet;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public static bool WriteListValue(Dictionary<string, Dictionary<string, string>> mapSectionName2Contents,

           object section, List<string> lstValue, string sNumKeyWrite = null, string keyPrefix = null)

       {

           try

           {

               if (mapSectionName2Contents.ContainsKey(section.ToString()))

               {

                   var lstKeys = new List<string>(mapSectionName2Contents[section.ToString()].Keys);

                   foreach (var item in lstKeys)

                   {

                       if (int.TryParse(item,out int nIndex))

                       {

                           mapSectionName2Contents[section.ToString()].Remove(item);

                       }

                       if(sNumKeyWrite != null)

                       {

                           mapSectionName2Contents[section.ToString()].Remove(sNumKeyWrite);

                       }

                   }

               }

               if (!string.IsNullOrWhiteSpace(sNumKeyWrite))

               {

                   WriteValue(mapSectionName2Contents, section, sNumKeyWrite, lstValue.Count);

               }

               CPadString pd = CPadString.Instance();

               int maxSpace = lstValue.Count().ToString().Length;

               for (int i = 0; i < lstValue.Count; i++)

               {

                   string key = pd.PadLeft((i + 1).ToString(), maxSpace);

                   if(keyPrefix != null)

                   {

                       key = keyPrefix + key;

                   }

                   WriteValue(mapSectionName2Contents, section, key, lstValue[i]);

               }

               if (lstValue.Count == 0)

               {

                   WriteValue(mapSectionName2Contents, section, null, null);

               }

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public bool WriteComment(object sectionName, List<string> lstComment)

       {

           try

           {

               string sSectionName = sectionName.ToString();

               if (!m_mapSectionName2LstComment.ContainsKey(sSectionName))

               {

                   m_mapSectionName2LstComment.Add(sSectionName, new List<string>());

               }

               m_mapSectionName2LstComment[sSectionName].AddRange(lstComment);

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public bool WriteComment(object sectionName, string sComment)

       {

           try

           {

               if (!WriteComment(m_mapSectionName2LstComment,sectionName,sComment))

               {

                   return false;

               }

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public static bool WriteComment(Dictionary<string, List<string>> mapSectionName2LstComment,object sectionName, string sComment)

       {

           try

           {

               string sSectionName = sectionName.ToString();

               if (!mapSectionName2LstComment.ContainsKey(sSectionName))

               {

                   mapSectionName2LstComment.Add(sSectionName, new List<string>());

               }

               if (!mapSectionName2LstComment[sSectionName].Contains(sComment))

               {

                   mapSectionName2LstComment[sSectionName].Add(sComment);

               }

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public bool RemoveSectionAndSectionComment(string section)

       {

           return RemoveSection(section) && RemoveSectionComment(section);

       }

       public bool RemoveSection(string sSectionName)

       {

           return ExceptionHandler.DoInHandler<bool>(() =>

           {

               if (MapSectionName2Contents.ContainsKey(sSectionName))

               {

                   MapSectionName2Contents.Remove(sSectionName);

               }

               return true;

           });

       }

  

       public bool RemoveSectionComment(string sSectionName)

       {

           return ExceptionHandler.DoInHandler<bool>(() =>

           {

               if (m_mapSectionName2LstComment.ContainsKey(sSectionName))

               {

                   m_mapSectionName2LstComment.Remove(sSectionName);

               }

               return true;

           }, false);

       }

       // end

       //删除某一行数据,并将下面的数据按顺序排列

       public bool RemovesRowAndOrderData(string section, List<int> indexList, string prefix = "")

       {

           try

           {

               if (indexList.Count == 0)

               {

                   return true;

               }

               var dic = ReadKeyValues(section);

               if (dic == null)

               {

                   return false;

               }

               var list = dic.Join(indexList, pair => pair.Key, i => i.ToString(), (pair, i) => pair.Key).ToList();

               foreach (var str in list)

               {

                   dic.Remove(str);

               }

               RemoveSection(section);

               int num = 0;

               int index = 1;

               foreach (KeyValuePair<string, string> pair in dic)

               {

                   if (int.TryParse(pair.Key, out num))

                   {

                       WriteValue(section, index, prefix + pair.Value);

                       index++;

                   }

                   else

                   {

                       WriteValue(section, pair.Key, prefix + pair.Value);

                   }

               }

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       private static bool WriteVersion(string filePath, Dictionary<string, Dictionary<string, string>> mapSectionName2Contents)

       {

           try

           {

               var dsEnvr = DsEnvironmentManager.Instance.CurrentDsEnvr;

               if (dsEnvr != null &&

                   dsEnvr.DsEnvrParam.DBM_DIR_PATH != null &&

                   filePath.StartsWith(dsEnvr.DsEnvrParam.DBM_DIR_PATH) &&

                   !filePath.StartsWith(dsEnvr.DsEnvrParam.ToolCfgDirName))

               {

                   WriteValue(mapSectionName2Contents, "数据版本", "版本号", dsEnvr.Version);

               }

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public bool Commit(bool bWithEndLine = true)

       {

           try

           {

               if (!Commit(Path,MapSectionName2Contents,m_mapSectionName2LstComment,bWithEndLine))

               {

                   return false;

               }

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       public static bool Commit(string filePath, Dictionary<string, Dictionary<string, string>> mapSectionName2Contents, Dictionary<string, List<string>> mapSectionName2LstComment, bool bWithEndLine = true)

       {

           try

           {

               var lstLine = new List<string>();

               WriteVersion(filePath,mapSectionName2Contents);

               foreach (var item in mapSectionName2Contents)

               {

                   string sectionName = item.Key;

                   if (mapSectionName2LstComment.ContainsKey(sectionName))

                   {

                       lstLine.AddRange(mapSectionName2LstComment[sectionName].Distinct());

                   }

                   string sectionLine = string.Format("[{0}]", sectionName);

                   lstLine.Add(sectionLine);

                   foreach (var content in item.Value)

                   {

                       string line = string.Format("{0}= {1}", content.Key, content.Value);

                       lstLine.Add(line);

                   }

                   if (bWithEndLine)

                   {

                       lstLine.Add("");

                   }

               }

               int index = filePath.LastIndexOf('\\');

               string dirPath = filePath.Substring(0, index);

               if (!Directory.Exists(dirPath))

               {

                   Directory.CreateDirectory(dirPath);

               }

               File.WriteAllLines(filePath, lstLine, Encoding.Default);

               return true;

           }

           catch (Exception ex) { ExceptionHandler.Instance.OnException(MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, ex); }

           return false;

       }

       #endregion

   }

}