我們在部署消息中間件的時候,可能需要對配置文件進行一些修改,正常情況下我們會直接到config路徑下手動修改,但是這種做法並不適用於一鍵安裝部署服務。所以我們需要實現一個接口供運營人員方便操作、修改配置信息。我實現了兩個版本的修改配置文件的接口(Java和C#),這裏先分享C#版的實現代碼。
1. 配置修改XML(ActiveMQ的通信端口和服務器控制檯端口)
public class ReadAndWriteXML
{
#region 屬性
/// <summary>
/// 存放xml內容的文件夾下的文件名
/// </summary>
private string JettyXML = "jetty.xml";
private string ActiveMQXML = "activemq.xml";
#endregion
#region 寫入xml
/// <summary>
///
/// </summary>
/// <param name="file">文件名</param>
/// <param name="key"></param>
/// <param name="value"></param>
public int WriteDoc(string path, string file, string value)
{
string SavePath = Path.Combine(path, "config");
//判斷是否存在文件夾
var DirectoryPath = Path.GetDirectoryName(SavePath); //獲取文件夾所在的路徑
if (!Directory.Exists(SavePath))
{
return 3; //文件夾不存在返回3
}
XmlDocument doc = new XmlDocument();
try
{
if (File.Exists(Path.Combine(SavePath, file)))
{
//如果文件存在 加載XML
doc.Load(Path.Combine(SavePath, file));
//分支判斷是jetty還是activemq
if (file.Equals(JettyXML))
{
XmlNode xmlnode = doc.SelectSingleNode(@"//bean[@id='jettyPort']");
xmlnode.LastChild.Attributes["value"].Value = value;
}
if (file.Equals("ActiveMQXML"))
{
XmlNode xmlnode = doc.SelectSingleNode("/beans/broker/transportConnectors/transportConnector[@name='openwire']");
xmlnode.Attributes["uri"].Value = "tcp://0.0.0.0:" + value + "?maximumConnections=1000&wireFormat.maxFrameSize=104857600";
}
doc.Save(file);
}
return 0;
}
catch (Exception e)
{
return 10;
}
}
}
2. 配置修改properties文件(ActiveMQ的管理員信息)
/// <summary>
///ReadProperties 的摘要說明
/// </summary>
public class ReadProperties : System.Collections.Hashtable
{
private ArrayList list = new ArrayList();
public ArrayList List
{
get { return list; }
set { list = value; }
}
/// <summary>
/// 構造函數
/// </summary>
/// <param name="fileName">要讀寫的properties文件名</param>
public ReadProperties(string path)
{
string filepath = Path.Combine(path, "config/users.properties");
Load(filepath);
}
/// <summary>
/// 重寫父類的方法,key值相當於用戶ID,Value值相當於Password
/// </summary>
/// <param name="key">鍵</param>
/// <param name="value">值</param>
public override void Add(object key, object value)
{
base.Add(key, value);
list.Add(key);
}
public override ICollection Keys
{
get
{
return list;
}
}
/// <summary>
/// 加載文件
/// </summary>
/// <param name="filePath">文件路徑</param>
public void Load(string filePath)
{
char[] convertBuf = new char[1024];
int limit;
int keyLen;
int valueStart;
char c;
string bufLine = string.Empty;
bool hasSep;
bool precedingBackslash;
using (StreamReader sr = new StreamReader(filePath))
{
while (sr.Peek() >= 0)
{
bufLine = sr.ReadLine();
limit = bufLine.Length;
keyLen = 0;
valueStart = limit;
hasSep = false;
precedingBackslash = false;
if (bufLine.StartsWith("#"))
keyLen = bufLine.Length;
while (keyLen < limit)
{
c = bufLine[keyLen];
if ((c == '=' || c == ':') & !precedingBackslash)
{
valueStart = keyLen + 1;
hasSep = true;
break;
}
else if ((c == ' ' || c == '\t' || c == '\f') & !precedingBackslash)
{
valueStart = keyLen + 1;
break;
}
if (c == '\\')
{
precedingBackslash = !precedingBackslash;
}
else
{
precedingBackslash = false;
}
keyLen++;
}
while (valueStart < limit)
{
c = bufLine[valueStart];
if (c != ' ' && c != '\t' && c != '\f')
{
if (!hasSep && (c == '=' || c == ':'))
{
hasSep = true;
}
else
{
break;
}
}
valueStart++;
}
string key = bufLine.Substring(0, keyLen);
string values = bufLine.Substring(valueStart, limit - valueStart);
if (key == "")
key += "#";
while (key.StartsWith("#") & this.Contains(key))
{
key += "#";
}
this.Add(key, values);
}
}
}
/// <summary>
/// 保存文件
/// </summary>
/// <param name="filePath">要保存的文件的路徑</param>
public void save(string filePath)
{
if (File.Exists(filePath))
{
File.Delete(filePath);
}
FileStream fileStream = File.Create(filePath);
StreamWriter sw = new StreamWriter(fileStream);
foreach (object item in list)
{
String key = (String)item;
String val = (String)this[key];
if (key.StartsWith("#"))
{
if (val == "")
{
sw.WriteLine(key);
}
else
{
sw.WriteLine(val);
}
}
else
{
sw.WriteLine(key + "=" + val);
}
}
sw.Close();
fileStream.Close();
}
}
調用的時候我們先調用構造方法實例化,然後調用Add方法即可。