很多程序员都有给源文件加注释的好习惯,但有时一个功能模块的文件加起来就有很多,所以给文件成批加上初始头注释可以稍微减轻负担。下面的程序主要实现了这样的功能。系统设计分为两部分(UI+后台算法),具体说有这样的结构:
窗体: MainForm(主窗体),InputForm(用于输入注释格式名的对话框),ActionForm(用于执行具体操作(插入注释、文本替换、输入目录路径)的具体模态窗口);
类: ActionTypeEnum,FileOperator,SystemLog,NoteLayoutUI,FolderTree
===============================================================================================================
下面是类的源码:
namespace AutoGenNote
{
/// <summary>
/// ActionTypeEnum 的摘要说明。
/// 系统枚举变量
/// </summary>
public class ActionTypeEnum
{
public enum ActionType
{
/// <summary>
/// 插入注释
/// </summary>
InsertNoteinHeader = 1,
/// <summary>
/// 文本替换
/// </summary>
ReplaceTextinFile =2,
/// <summary>
/// 输入目录名
/// </summary>
InputFolderName=3
}
public class KeyWord
{
public const string FileName ="$FileName";
public const string FilePath ="$FilePath";
public const string CreateDate = "$CreateDate";
}
public ActionTypeEnum()
{
}
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
namespace AutoGenNote
{
/// <summary>
/// FileOperator 的摘要说明。
/// 文件操作:插入文本,替换文本
/// </summary>
public class FileOperator
{
private string m_strFileName;
private string m_strInsertText;
private string m_strReplaceText;
private string m_strInsteadText;
属性列表
构造函数
/// <summary>
/// 在文件头部插入文本
/// </summary>
/// <returns>-1:文件不存在或插入文本为空,-2:文件只读,-3:或已存在注释;1:插入成功</returns>
public int InsertTextinHeader()
{
if (this.FileName == "" || this.InsertText == "")
{
return -1;
}
if (!File.Exists(this.FileName))
{
return -1;
}
System.IO.FileStream _fileStream;
_fileStream = File.OpenWrite(this.FileName);
if (!_fileStream.CanWrite)
{
_fileStream.Close();
return -2;
}
_fileStream.Close();
if (HaveOldNotes())
{
DialogResult dlgResult = MessageBox.Show("文件中已存在相似注释! 继续吗?","提示",System.Windows.Forms.MessageBoxButtons.YesNo,MessageBoxIcon.Warning);
if (dlgResult == DialogResult.No)
{
_fileStream.Close();
return -3;
}
}
char[] chrArr = {' ',' '};
string[] strArrNote = this.InsertText.ToString().Split(chrArr);
ArrayList strArrLine = new ArrayList();
int iCount = strArrNote.Length;
for(int i=0;i<iCount;i++)
{
strArrLine.Add(strArrNote[i]);
}
System.IO.StreamReader _sr = new StreamReader(this.FileName);
while(_sr.Peek()!=-1)
{
string strCurLine = _sr.ReadLine();
strArrLine.Add(strCurLine);
}
_sr.Close();
System.IO.StreamWriter _sw = File.CreateText(this.FileName);
foreach(string strLine in strArrLine)
{
_sw.WriteLine(strLine);
}
_sw.Close();
return 1;
}
/// <summary>
/// 简单判断是否有相似注释存在,只比较第一行
/// </summary>
/// <returns>相同true,不相同false</returns>
private bool HaveOldNotes()
{
System.IO.TextReader _textReader;
_textReader = File.OpenText(this.FileName);
string strHeaderline = _textReader.ReadLine();
string strInsertText = this.InsertText.ToString();
int iIndex = strInsertText.IndexOf(" ");
if (iIndex>0)
{
strInsertText = strInsertText.Substring(0,iIndex);
}
try
{
if (strInsertText.CompareTo(strHeaderline) ==0)
{
return true;
}
else
{
return false;
}
}
catch
{
//
}
finally
{
_textReader.Close();
}
return false;
}
/// <summary>
/// 在文件中替换文本
/// </summary>
/// <returns>-1:文件不存在或替换文本为空,-2:文件只读;1:替换成功</returns>
public int ReplaceTextinFile()
{
if (this.FileName == "" || this.ReplaceText == "")
{
return -1;
}
if (!File.Exists(this.FileName))
{
return -1;
}
System.IO.FileStream _fileStream;
_fileStream = File.OpenWrite(this.FileName);
if (!_fileStream.CanWrite)
{
_fileStream.Close();
return -2;
}
_fileStream.Close();
System.IO.StreamReader _sr = new StreamReader(this.FileName);
ArrayList strArrLine = new ArrayList();
while(_sr.Peek()!=-1)
{
string strCurLine = _sr.ReadLine();
strArrLine.Add(strCurLine.Replace(this.ReplaceText,this.InsteadText));
}
_sr.Close();
System.IO.StreamWriter _sw = File.CreateText(this.FileName);
foreach(string strLine in strArrLine)
{
_sw.WriteLine(strLine);
}
_sw.Close();
return 1;
}
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
namespace AutoGenNote
{
/// <summary>
/// SystemLog 的摘要说明。
/// 生成系统运行结果说明
/// </summary>
public class SystemLog
{
public SystemLog()
{
}
public static void WriteMessage(ref System.Windows.Forms.RichTextBox objRichTextBox,string strMessage)
{
objRichTextBox.AppendText(System.DateTime.Now.ToString()+": "+strMessage);
}
public static void WritelnMessage(ref System.Windows.Forms.RichTextBox objRichTextBox,string strMessage)
{
objRichTextBox.AppendText(System.DateTime.Now.ToString()+": "+strMessage+" ");
}
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
namespace AutoGenNote
{
/// <summary>
/// NoteLayoutUI 的摘要说明。
/// 用于格式创建、修改、删除等操作
/// </summary>
public class NoteLayoutUI
{
string m_strDirPath;
string m_strFilePath;
public NoteLayoutUI()
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="strDirPath">存放路径</param>
/// <param name="strFilePath">文件名</param>
public NoteLayoutUI(string strDirPath,string strFilePath)
{
this.m_strDirPath = strDirPath;
this.m_strFilePath = strFilePath;
}
/// <summary>
/// 从当前目录下的NoteLayoutLib目录中的NoteLayoutLib.xml中读取注释格式列表
/// </summary>
/// <param name="strDefaultName">缺省格式</param>
/// <returns>以格式名为主键的Hashtable</returns>
public static Hashtable LoadNoteLayout(ref string strDefaultName)
{
string strDirPath = Path.GetFullPath(".\NoteLayoutLib");
string strFilePath = strDirPath+"\NoteLayoutLib.xml";
if (!Directory.Exists(strDirPath))
{
Exception exDir = new Exception("目录NoteLayoutLib不存在!");
throw(exDir);
}
if (!File.Exists(strFilePath))
{
Exception exFile = new Exception("目录NoteLayoutLib下文件NoteLayoutLib.xml不存在!");
throw(exFile);
}
System.IO.StreamReader srd;
try
{
srd = File.OpenText(strFilePath);
}
catch(Exception exReadFile)
{
throw(exReadFile);
}
Hashtable objHashTable = new Hashtable();
XmlDocument objXmlDoc = new XmlDocument();
objXmlDoc.Load(srd);
System.Xml.XmlNodeList objNoteNodeList = objXmlDoc.SelectNodes("NoteLayoutList/NoteLayout");
int iNoteCount = objNoteNodeList.Count;
for(int i=0; i<iNoteCount;i++)
{
string strName = objNoteNodeList[i].Attributes["name"].Value.ToString();
string strNoteLayout = objNoteNodeList[i].InnerText.ToString();
objHashTable.Add(strName,strNoteLayout);
}
//get the default select index
System.Xml.XmlNode objDefaultNoteNode= objXmlDoc.SelectSingleNode("NoteLayoutList/DefaultSelectedName");
strDefaultName = objDefaultNoteNode.InnerText.ToString();
srd.Close();
return objHashTable;
}
/// <summary>
/// 更新注释格式
/// </summary>
/// <param name="strName">注释格式名</param>
/// <param name="strValue">注释格式内容</param>
/// <param name="bDefault">是否设为缺省注释格式,true/false</param>
public static void UpdateNoteLayout(string strName,string strValue,bool bDefault)
{
string strDirPath = Path.GetFullPath(".\NoteLayoutLib");
string strFilePath = strDirPath+"\NoteLayoutLib.xml";
if (!Directory.Exists(strDirPath))
{
Directory.CreateDirectory(strDirPath);
}
if (!File.Exists(strFilePath))
{
System.IO.StreamWriter srd;
srd = File.CreateText(strFilePath);
srd.WriteLine("<?xml version="1.0" encoding="utf-8"?><NoteLayoutList>");
srd.WriteLine("<NoteLayout name=""+strName+"">");
srd.WriteLine(strValue);
srd.WriteLine("</NoteLayout><DefaultSelectedName></DefaultSelectedName></NoteLayoutList>");
srd.Close();
return;
}
XmlDocument objXmlDoc = new XmlDocument();
objXmlDoc.Load(strFilePath);
//检查XML合法性
if(!XmlValid(objXmlDoc))
{
Exception exInvalidXml = new Exception("XML文件已被损坏!");
throw(exInvalidXml);
}
System.Xml.XmlNodeList objNoteNodeList = objXmlDoc.SelectNodes("NoteLayoutList/NoteLayout");
foreach(XmlNode objNode in objNoteNodeList)
{
if (objNode.Attributes["name"].Value.ToString() == strName.Trim())
{
objNode.InnerText = strValue;
break;
}
}
if (bDefault)//设为默认
{
System.Xml.XmlNode objDefaultNode = objXmlDoc.SelectSingleNode("NoteLayoutList/DefaultSelectedName");
objDefaultNode.InnerText = strName.Trim();
}
objXmlDoc.Save(strFilePath);
}
/// <summary>
/// 删除注释格式
/// </summary>
/// <param name="strName">注释格式名</param>
public static void DeleteNoteLayout(string strName)
{
string strDirPath = Path.GetFullPath(".\NoteLayoutLib");
string strFilePath = strDirPath+"\NoteLayoutLib.xml";
int iFound = 0;
if (!Directory.Exists(strDirPath))
{
Exception exDir = new Exception("目录NoteLayoutLib不存在!");
throw(exDir);
}
if (!File.Exists(strFilePath))
{
Exception exFile = new Exception("目录NoteLayoutLib下文件NoteLayoutLib.xml不存在!");
throw(exFile);
}
XmlDocument objXmlDoc = new XmlDocument();
objXmlDoc.Load(strFilePath);
//检查XML合法性
if(!XmlValid(objXmlDoc))
{
Exception exInvalidXml = new Exception("XML文件已被损坏!");
throw(exInvalidXml);
}
System.Xml.XmlNodeList objNoteNodeList = objXmlDoc.SelectNodes("NoteLayoutList/NoteLayout");
System.Xml.XmlNode objRoot = objXmlDoc.SelectSingleNode("NoteLayoutList");
foreach(XmlNode objNode in objNoteNodeList)
{
if (objNode.Attributes["name"].Value.ToString() == strName.Trim())
{
objRoot.RemoveChild(objNode);
iFound = 1;
break;
}
}
if (iFound == 0)
{
Exception exInvalidXml = new Exception("该格式不存在!");
throw(exInvalidXml);
}
//保存到物理文件
objXmlDoc.Save(strFilePath);
}
/// <summary>
/// 新增注释格式
/// </summary>
/// <param name="strName">注释格式名</param>
/// <param name="strValue">注释格式内容</param>
/// <param name="bDefault">是否设为缺省注释格式,true/false</param>
public static void SaveNoteLayout(string strName,string strValue,bool bDefault)
{
string strDirPath = Path.GetFullPath(".\NoteLayoutLib");
string strFilePath = strDirPath+"\NoteLayoutLib.xml";
if (!Directory.Exists(strDirPath))
{
Directory.CreateDirectory(strDirPath);
}
if (!File.Exists(strFilePath))
{
System.IO.StreamWriter srd;
srd = File.CreateText(strFilePath);
srd.WriteLine("<?xml version="1.0" encoding="utf-8"?><NoteLayoutList>");
srd.WriteLine("<NoteLayout name=""+strName+"">");
srd.WriteLine(strValue);
srd.WriteLine("</NoteLayout><DefaultSelectedName></DefaultSelectedName></NoteLayoutList>");
srd.Close();
return;
}
XmlDocument objXmlDoc = new XmlDocument();
objXmlDoc.Load(strFilePath);
//检查XML合法性
if(!XmlValid(objXmlDoc))
{
Exception exInvalidXml = new Exception("XML文件已被损坏!");
throw(exInvalidXml);
}
System.Xml.XmlNodeList objNoteNodeList = objXmlDoc.SelectNodes("NoteLayoutList/NoteLayout");
foreach(XmlNode objNode in objNoteNodeList)
{
if (objNode.Attributes["name"].Value.ToString() == strName.Trim())
{
Exception exSameName = new Exception("该格式已存在!");
throw(exSameName);
}
}
//插入新节点
XmlElement objXmlElement = objXmlDoc.CreateElement("NoteLayout");//创建一个<NoteLayout>节点
objXmlElement.SetAttribute("name",strName);//设置该节点name属性
objXmlElement.InnerText = strValue;
System.Xml.XmlNode objRoot = objXmlDoc.SelectSingleNode("NoteLayoutList");
objRoot.AppendChild(objXmlElement);
if (bDefault)//设为默认
{
System.Xml.XmlNode objDefaultNode = objXmlDoc.SelectSingleNode("NoteLayoutList/DefaultSelectedName");
objDefaultNode.InnerText = strName.Trim();
}
objXmlDoc.Save(strFilePath);
}
/// <summary>
/// 简单验证xml文档
/// </summary>
/// <param name="objXmlDoc">xml文档</param>
/// <returns>true/false</returns>
public static bool XmlValid(XmlDocument objXmlDoc)
{
if (objXmlDoc.SelectSingleNode("NoteLayoutList")== null)
{
return false;
}
if (objXmlDoc.SelectSingleNode("NoteLayoutList/DefaultSelectedName")== null)
{
return false;
}
return true;
}
/// <summary>
/// 获取当前设置的默认注释格式名
/// </summary>
/// <returns></returns>
public static string GetDefaultNoteLayout()
{
//string strDirPath = "\NoteLayoutLib";
string strFilePath = Path.GetFullPath(".\NoteLayoutLib\NoteLayoutLib.xml");
if (!File.Exists(strFilePath))
{
return "";
}
XmlDocument objXmlDoc = new XmlDocument();
objXmlDoc.Load(strFilePath);
//检查XML合法性
if(!XmlValid(objXmlDoc))
{
return "";
}
System.Xml.XmlNode objDefaultNode = objXmlDoc.SelectSingleNode("NoteLayoutList/DefaultSelectedName");
return objDefaultNode.InnerText;
}
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
namespace AutoGenNote
{
/// <summary>
/// FolderTree 的摘要说明。
/// 用于生成目录树和获取节点信息等操作。
/// </summary>
public class FolderTree
{
public FolderTree()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 生成指定路径下的目录树,过滤显示文件
/// </summary>
/// <param name="objTreeView">目录树</param>
/// <param name="strPath">指定路径</param>
/// <param name="strFileFilter">过滤格式</param>
public static void FillTree(ref System.Windows.Forms.TreeView objTreeView,string strPath,string strFileFilter)
{
//若给定是文件名,则生成“file”节点
if (File.Exists(strPath))
{
System.Windows.Forms.TreeNode objFileNode = new TreeNode();
strPath = strPath.TrimEnd('\');
objFileNode.Tag = "file";
objFileNode.Text = strPath;
objTreeView.Nodes.Add(objFileNode);
return;
}
//生成根节点
System.Windows.Forms.TreeNode objNode = new TreeNode();
strPath = strPath.TrimEnd('\');
objNode.Tag = "folder";
objNode.Text = strPath;
objTreeView.Nodes.Add(objNode);
//递归获取目录和文件
strPath+= "\";
GetFolders(strPath,strFileFilter,objTreeView.Nodes[0]);
}
/// <summary>
/// 递归获取文件夹和相关文件,并填充到节点
/// </summary>
/// <param name="path">目录路径</param>
/// <param name="nodes">填充节点</param>
private static void GetFolders(string path,string strFileFilter,System.Windows.Forms.TreeNode node)
{
//获取子目录
string[] dirs = Directory.GetDirectories(path);
foreach( string p in dirs )
{
TreeNode objDirNode = new TreeNode(p.Substring(path.Length));
objDirNode.Tag = "folder";
node.Nodes.Add(objDirNode);
}
//获取目录内文件,过滤文件
//e.g. strFileFilter="*.aspx"
if (strFileFilter.Trim() =="")
{
strFileFilter = "*.*";
}
string[] files = Directory.GetFiles(path,strFileFilter);
foreach(string p in files )
{
TreeNode objFileNode = new TreeNode(p.Substring(path.Length));
objFileNode.Tag = "file";
node.Nodes.Add(objFileNode);
}
//增加子文件夹及其文件(递归)
int iSubNodesCount = node.Nodes.Count;
for( int i = 0;i<iSubNodesCount;i++)
{
if(node.Nodes[i].Tag.ToString() == "folder")
{
GetFolders(dirs[i]+"\",strFileFilter,node.Nodes[i]);
}
}
}
/// <summary>
/// 以数组形式返回所有文件的全名
/// </summary>
/// <param name="objTreeView">目录Tree</param>
/// <returns>string[]</returns>
public static string[] GetAllFileNodesInfo(System.Windows.Forms.TreeView objTreeView)
{
int iNodesCount = objTreeView.Nodes.Count;
if (iNodesCount <=0)
{
return (new string[0]);
}
string strFileList = "";
for(int i=0;i<iNodesCount;i++)
{
strFileList += GetSubFileNodesInfo(objTreeView.Nodes[i])+"|";
}
strFileList = strFileList.TrimEnd('|');
return strFileList.Split('|');
}
/// <summary>
/// 递归获取子节点的文件全名
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private static string GetSubFileNodesInfo(System.Windows.Forms.TreeNode node)
{
string strFileList = "";
int iSubNodesCount = node.Nodes.Count;
if (iSubNodesCount ==0 && node.Tag.ToString() == "file")
{
return node.FullPath.ToString().TrimEnd('|');
}
for( int i = 0;i<iSubNodesCount;i++)
{
string strTemp = GetSubFileNodesInfo(node.Nodes[i]);
strFileList += (strTemp.Trim()==""?"":strTemp+"|");
}
return strFileList.TrimEnd('|');
}
}
}
====================================================================================
在页面交互时主要是通过判断操作类型,执行线程,执行窗口上的Cancel按钮可终止执行线程。所以这里需要用到一些多线程编程的简单方法。需要说明的是在执行窗口关闭时,要在窗体的Closing事件里终止执行线程,否则会造成下次操作同一文件时产生冲突。
此外,注释格式主要用xml文件存储(此时要注意xml的编码格式,否则会出现乱字符),在插入注释时还会先替换注释关键字,比如如果注释中有$FileName,则会被替换为当前文件名。另外,还提供了文本替换功能。整体上结构相当简单的。但对于熟悉一下C#的winform编程还是有帮助的。
窗体: MainForm(主窗体),InputForm(用于输入注释格式名的对话框),ActionForm(用于执行具体操作(插入注释、文本替换、输入目录路径)的具体模态窗口);
类: ActionTypeEnum,FileOperator,SystemLog,NoteLayoutUI,FolderTree
===============================================================================================================
下面是类的源码:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
====================================================================================
在页面交互时主要是通过判断操作类型,执行线程,执行窗口上的Cancel按钮可终止执行线程。所以这里需要用到一些多线程编程的简单方法。需要说明的是在执行窗口关闭时,要在窗体的Closing事件里终止执行线程,否则会造成下次操作同一文件时产生冲突。
此外,注释格式主要用xml文件存储(此时要注意xml的编码格式,否则会出现乱字符),在插入注释时还会先替换注释关键字,比如如果注释中有$FileName,则会被替换为当前文件名。另外,还提供了文本替换功能。整体上结构相当简单的。但对于熟悉一下C#的winform编程还是有帮助的。
浙公网安备 33010602011771号