基于正则的INI读写工具类,支持加密解密

原文:基于正则的INI读写工具类,支持加密解密

看到这个标题,有人会问,现在都用xml做配置文件了,谁还用INI文件啊!下面来简单对比一下xml和ini:

  1、XML功能强大表达能力强,同时扩展性好。
  2、它的主要优势是异构平台的整合、通讯。
  3、缺点主要是使用复杂,运行库占用的资源较多。
  4、如果多个程序进行数据交换或是跨平台通讯则使用功能强大的XML;

  5、INI虽表达能力不强,但是简单实用,接口方便。如果是用于应用程序的配置INI文件就够了。

至于哪个更好,应该用哪个,可以根据自己爱好和需求。个人感觉INI文件操作简单,就是读取文件,处理字符串,保存到文件,可谓是简单粗暴。而且内容也比较友好,没有冗余的东西。

  由于最近项目中用到INI文件,所以抽空编写了一个Helper,取名交INIHelper。这里先不给出它的源码,先来看下他的用法。

一、INIHelper的用法                                                                     

  这里为了做演示,我建了一个C# 控制台应用程序,随便起了个名字,加入了INIHelper这个类。项目结构如图:

在Debug目录下面添加了一个config.ini的文件,内容如下:

下面我们用这个Helper来读取这个INI文件的所有内容,代码如下:

class Program
   {
      static void Main(string[] args)
      {
         try
         {
            INIHelper helper = new INIHelper("config.ini");
            Console.WriteLine(helper.GetValueByName("DBName"));
            Console.WriteLine(helper.GetValueByName("UserName"));
            Console.WriteLine(helper.GetValueByName("PassWord"));
            Console.WriteLine(helper.GetValueByName("Version"));
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
         }

         Console.Read();
      }
   }

输出结果如下:

是不是很方便,这里还有另外一种写法,代码如下:

class Program
   {
      static void Main(string[] args)
      {
         try
         {
            INIHelper helper = new INIHelper();
            helper.LoadINI("config.ini");
            Console.WriteLine(helper.GetValueByName("DBName"));
            Console.WriteLine(helper.GetValueByName("UserName"));
            Console.WriteLine(helper.GetValueByName("PassWord"));
            Console.WriteLine(helper.GetValueByName("Version"));
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
         }

         Console.Read();
      }
   }

代码中加粗的部分就是另外一种写法,一种方法是在构造时加载ini文件,另外一种方法时在需要的时候加载。到这里读取ini文件的就说完了,下面来说一下修改ini文件。这里我们来修改ini文件密码为root,然后保存到ini文件中,来看看代码怎么写:

class Program
   {
      static void Main(string[] args)
      {
         try
         {
            INIHelper helper = new INIHelper();
            helper.LoadINI("config.ini");
            helper.SetValueByName("PassWord", "root");
            helper.SaveINI();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
         }

         Console.Read();
      }
   }

首先加载ini文件,然后调用SetValueByName方法修改密码,最后调用SaveINI方法保存。保存后,可以打开ini文件看到内容变了,这里就不再截图了。其还支持加密解密,这样我们的配置文件内容就不会被被人看到和随意修改了,加密后的效果如下:

 

 

二、揭开INIHelper神秘的面纱                                                          

  下面来看看INIHelper的具体实现,首先来看构造方法和LoadINI,其实现代码如下:

      private string newLine = "\r\n";  //换行符
      private string filePath = string.Empty; //文件名称
      private string fileContent = string.Empty; //文件内容

      public INIHelper() { }
      /// <summary>
      /// 有参构造方法,直接读取INI文件
      /// </summary>
      /// <param name="filePath"></param>
      public INIHelper(string filePath)
      {
         this.LoadINI(filePath);
      }

      /// <summary>
      /// 加载并读取INI文件
      /// </summary>
      /// <param name="fileName">文件路径</param>
      public void LoadINI(string filePath)
      {
         if (filePath.Trim().Length > 0)
         {
            this.filePath = filePath;
            ReadINIFile();
         }
         else
         {
            throw new Exception("Invalid file name!");
         }
      }

可以看到在有参构造方法里面调用了LoadINI方法,所以等价于调用无参构造函数然后调用LoadINI方法。LoadINI方法里面首先判断文件路径是否合法,合法的话就读取ini文件,否则抛出异常。ReadINIFile方法就是读取文件内容,然后赋给fileContent,其实现如下:

/// <summary>
      /// 读取INI文件
      /// </summary>
      private void ReadINIFile()
      {
         if (File.Exists(this.filePath))
         {
            try
            {
               using (StreamReader sr = new StreamReader(this.filePath))
               {
                  this.fileContent = sr.ReadToEnd();
                  this.fileContent = EncryptionAndDecryption(fileContent); //解密
                  //如果文件内容为空或者没有换行符,则认为是无效的INI文件。
                  if (fileContent.Trim().Length <= 0 || !fileContent.Contains("\n"))
                  {
                     throw new Exception("Invalid ini file");
                  }
                  else
                  {
                     //保存文件默认换行符
                     if (!fileContent.Contains(newLine))
                     {
                        this.newLine = "\n";
                     }
                  }
               }
            }
            catch (Exception ex)
            {
               throw new Exception("Read file error! Error Message:" + ex.Message);
            }
         }
         else
         {
            throw new Exception("File " + filePath + " not found!");
         }
      }

这个已经包含了加密解密的方法,首先读取文件内容,解密,然后判断文件是否合法,及是否有为空和是否有换行符,然后判断里面的换行符是否为默认值,否则修改newLine为文件默认的换行符。(大家可以修改代码,自定分割符。默认是支持\r\n或\n)

/// <summary>
      /// 读取INI文件某个配置项的值
      /// </summary>
      /// <param name="fieldName"></param>
      /// <returns></returns>
      public string GetValueByName(string fieldName)
      {
         fileContent = fileContent.Replace(newLine, ";");
         fileContent = fileContent.Replace(" ", "");
         fileContent = fileContent.EndsWith(";") ? fileContent : fileContent + ";";
         Regex reg = new Regex("(?<=" + fieldName + "=).*?(?=;)");
         Match m = reg.Match(fileContent);
         return m.Value;
      }

      /// <summary>
      /// 修改INI文件某个配置项的值
      /// </summary>
      /// <param name="fieldName"></param>
      /// <param name="value"></param>
      public void SetValueByName(string fieldName, string value)
      {
         string reg = "(?<=" + fieldName + "=).*?(?=;)";
         fileContent = Regex.Replace(fileContent, reg, value);
      }

这个是读取和修改某个配置项的方法,使用正则表达式进行匹配。修改只是修改fileContent的值,并不执行保存。

/// <summary>
      /// 保存对INI文件的修改
      /// </summary>
      public void SaveINI()
      {
         try
         {
            fileContent = fileContent.Replace(";", newLine); //替换换行符
            fileContent = EncryptionAndDecryption(fileContent); //加密
            using (StreamWriter sw = new StreamWriter(filePath))
            {
               sw.Write(fileContent);
               sw.Close();
            }
         }
         catch (Exception ex)
         {
            throw new Exception("Save file error! Error Message:" + ex.Message);
         }
      }

      /// <summary>
      /// 加密解密算法,使用异或算法
      /// </summary>
      /// <param name="str"></param>
      public string EncryptionAndDecryption(string str)
      {
         byte key = 32;
         byte[] buffer = Encoding.Default.GetBytes(str);
         for (int i = 0; i < buffer.Length; i++)
         {
            buffer[i] ^= key;
         }
         return Encoding.Default.GetString(buffer);
      }

SaveINI执行加密后保存到ini文件,这里给出了简单的对称加密算法,大家使用时可以使用自定义的加密算法。

注意:笫一次读取配置文件由于没有加密,调用了解密算法,所以会出现文件无效的异常。这里需要先加密保存一次,然后就好了。

 

源码下载

 

时间: 2024-09-25 12:58:56

基于正则的INI读写工具类,支持加密解密的相关文章

把内容写入指定目录指定文件的java文件工具类,支持日期格式目录名的生成

package com.yanek.test; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.text.SimpleDat

轻松把玩HttpClient之封装HttpClient工具类(一)(现有网上分享中的最强大的工具类)

       搜了一下网络上别人封装的HttpClient,大部分特别简单,有一些看起来比较高级,但是用起来都不怎么好用.调用关系不清楚,结构有点混乱.所以也就萌生了自己封装HttpClient工具类的想法.要做就做最好的,本工具类支持插件式配置Header.插件式配置httpclient对象,这样就可以方便地自定义header信息.配置ssl.配置proxy等.        是不是觉得说的有点悬乎了,那就先看看调用吧: public static void testSimple() thro

ScopServ-VoIP 2.1.1发布 基于Web的Asterisk管理工具

ScopServ-VoIP 2.1.1该版本完美的支持DAHDI和Asterisk1.8.现在可以轻松地开关/切换不同版本之间的Asterisk(1.4和1.8)和ScopServ电话服务器直接从Web界面(GUI)(1.4,2.0和2.1). ScopServ-VoIP是一个基于Web的Asterisk管理工具.支持多语言.多用户.个人IVR和最终用户UI等. 关于Asterisk Asterisk 是一个开放源代码的软件VoIP PBX系统,它是一个运行在Linux环境下的纯软件实施方案.A

Java工作利器之常用工具类(四)——Json工具类,使用正则支持xml与json互转

看到这个题目是不是大部分人都不屑一顾,的确基本上每个java程序猿都写过json工具类,也有很多人都使用json-lib.jar封装过类似的功能,但是我这里使用了正则来支持xml与json的互转,减少了jar包的引入.基本上满足了需求.当然如果你需要更强大的功能,还是最好使用json-lib来实现. 主要看一下工具类中的转换json和转换成xml的方法吧. 1. xml转json 具体就不多说了,我是采用的笨方法,多次使用正则进行替换的.比较好的一点儿是支持xml元素属性.如果xml节点有属性会

代码片段:基于 JDK 8 time包的时间工具类 TimeUtil

知识的工作者必须成为自己时间的首席执行官. 前言 这次泥瓦匠带来的是一个好玩的基于 JDK 8 time包的时间工具类 TimeUtil.本意,用 JDK 8 写个实战的时间工具类,初版泥瓦匠写的很不好,后来雨神分分钟将这个代码优化优化,谢谢雨神.就此分享下这个代码,让更多的人看到~ 一. Java 8 time包 从 Java 1.0 有个 Date 类,想必大家不陌生,后面有了 Calendar 类(被废弃 ).API 确实比较难用,因此 Java 8 引入 java.time API,这次

Java正则表达式(二)、常用正则工具类

        此类提供日常开发中常用的正则验证函数,比如:邮箱.手机号.电话号码.身份证号码.日期.数字.小数.URL.IP地址等.使用Pattern对象的matches方法进行整个字符匹配,调用该方法相当于:          Pattern p = Pattern.compile(regex);         Matcher m = p.matcher(input);         return m.matches(); 每个正则可能还有待优化的地方,您如有更好的方式实现某一个功能的验

.Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient)

client|web|多线程|客户端|下载 /* .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient) * Reflector 了一下 System.Net.WebClient ,重载或增加了若干: * DownLoad.Upload 相关方法! * DownLoad 相关改动较大! * 增加了 DataReceive.ExceptionOccurrs 事件! * 了解服务器端与客户端交互的 HTTP 协议参阅: * 使文件

常用的读写ini文件的类

using System;using System.IO;using System.Runtime.InteropServices;using System.Text;using Microsoft.Win32; namespace Wjb.ReadOrWriteIniAndReg{ /// <summary> /// RWIni 的摘要说明. /// 读写ini文件类 /// 类库开发:吴剑冰 /// 时间:2003年10月20日 /// 功能:读写INI文件 /// </summar

java实现的正则工具类_java

本文实例讲述了java实现的正则工具类.分享给大家供大家参考.具体如下: 这里实现的正则工具类适用于:正则电话号码.邮箱.QQ号码.QQ密码.手机号 java代码如下: package com.zhanggeng.contact.tools; /** * RegexTool is used to regex the string ,such as : phone , qq , password , email . * * @author ZHANGGeng * @version v1.0.1 *