花了一个晚上,连查MSDN,带编写代码和调试,终于写出来了,中间还看了看姚明的NBA比赛。哈哈,好开心啊~ 第一次动手写C#的程序呢 ^_^
非常简单的项目,大牛们不要笑话我啊~ 多提宝贵意见。进入正题!
背景:
公司的项目中,把一些有用的信息写成了Log,出了问题的时候,也好给程序员调试。由于测试部门的不停测试,这个log随时间不断变大,真的出现问题的时候,可能程序员已经没有耐心和手段来看log了。如果bug是可以重现的,那么重新记录log就可以解决问题;但是一些log很难重现,那么这个巨大的log中可能就含有重要的信息。故此,我想写个程序,抽取其中关心的信息。
Log的组织:
log中记录的是服务器和客户端之间交互的xml packet,并有记录时间,优先级等等。
故此结构为空行 -> 信息 -> xml -> 空行 循环。其中xml节点有type属性来标示何种xml packet
调试时,我们想抽取的基本都是有特定type的xml packet。
实践:
思路基本上就是:删掉空行,删掉信息行,组织成xml,查询特定type属性的xml
于是,我开始动手用VC++来实现(公司的开发语言是VC++啦,很少接触过C#)。通过CFile来操作文件,通过CMarkup来操作xml。但是这两个操作都非常不爽。花了好大力气,写了很多代码,有些功能还是没实现。
郁闷之余,想起近来晚上回家经常看博客堂的一些文章,其中有些介绍C#使用正则表达式和xml的,于是突发奇想,要用C#来实现。
代码:
经过一番努力,做出来了,哈哈,下面列出核心代码,其中红色的部分是关键代码,或者算法的核心 ![]()
String sourcepath = @"c:/logger.log";
String destpath = @"c:/trimlogger.log";
#region Trim Log File
try
{
// if destination file exists, delete it and create a new file
if (File.Exists(destpath))
{
File.Delete(destpath);
}
// define Stream Reader and Writer
StreamWriter sw = new StreamWriter(destpath);
StreamReader sr = new StreamReader(sourcepath);
// make the log as a xml file by add root tag "<log>"
sw.WriteLine("<log>");
// use RegularExpress to trim the non-xml part of log
while (sr.Peek() >= 0) // 判断文件是否结束的方法
{
// get a line
String strLine;
strLine = sr.ReadLine();
// use regulare expression to check whether begin with '<'
// Create a new Regex object.
Regex r = new Regex("^<"); // 表示该字符串以‘<’开头
// Find a single match in the string.
Match m = r.Match(strLine);
// if success then write it to the destiny file :)
if (m.Success)
sw.WriteLine(strLine);
}
sw.WriteLine("</log>");
// close reader and writer
sw.Close();
sr.Close();
}
catch (Exception ee)
{
label1.Text = ee.ToString();
}
#endregion
#region search in the xml tag
// create a xmldocument
XmlDocument xmlDoc=new XmlDocument();
xmlDoc.Load(destpath);
// delete the destpath to write in it again
File.Delete(destpath);
StreamWriter swsw = new StreamWriter(destpath);
// 获取所有节点
XmlNode nodeLog = xmlDoc.SelectSingleNode("log");
XmlNodeList nodeList=nodeLog.ChildNodes;
//遍历所有子节点
foreach(XmlNode xn in nodeList)
{
//将子节点类型转换为XmlElement类型
XmlElement xe=(XmlElement)xn;
//如果type属性值不为"ggg", 删除
if(xe.GetAttribute("type")=="ggg")
{
swsw.WriteLine(xe.OuterXml);
}
}
// save back
swsw.Close();
#endregion
哈哈,好简单啊,短短数行,一切搞定。以后要多用用C#呢 :)

作者为抽取日志文件中特定type的xml packet信息,起初用VC++实现遇到困难,后改用C#结合正则表达式和xml操作完成。通过删除空行和信息行、组织成xml、查询特定type属性的xml等步骤,成功实现功能,代码简洁。

654

被折叠的 条评论
为什么被折叠?



