DavidJGu's Blog

       尼采说,宁可追求虚无也不能无所追求!  Keeping is harder than winning
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

为源程序加头注释--C#小程序之初体验

Posted on 2004-09-23 16:03  Let's DotNet  阅读(1044)  评论(0)    收藏  举报
很多程序员都有给源文件加注释的好习惯,但有时一个功能模块的文件加起来就有很多,所以给文件成批加上初始头注释可以稍微减轻负担。下面的程序主要实现了这样的功能。系统设计分为两部分(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);
            
foreachstring 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;
            
forint 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('|');
            }

            
forint 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编程还是有帮助的。