最近需要按照GJB编写研制总结报告,涉及到代码统计,之前是按照网上提到的正则表达式进行初步统计,再由人工进行详细统计。效率低下,通过查询后,发现自己实现好一些,用了2个小时,做了这个小demo。
参考文章:https://blog.csdn.net/chr23899/article/details/43671281
https://www.cnblogs.com/fuyun2000/archive/2013/06/16/3138937.html
下面讲一下思路:
1、选定一个文件夹做为根目录,遍历该根目录下所有的文件夹及文件。
2、将需要统计代码的文件进行标红。
3、开始对标红的文件进行统计,除去引用,以及系统生成的代码,对注释和剩余的代码进行统计。
4、将统计结果导出成word表格,方便使用。
一、遍历、标红:
private void LoadDirectory(string path, TreeNode nodeTemp)
{
DirectoryInfo info = new DirectoryInfo(path);
//获取文件夹后缀名
string str = info.Extension;
//FullName:获取全路径
str = info.FullName;
TreeNode node = new TreeNode();
if (info.Exists)
{
if (info.Attributes.ToString().Contains(FileAttributes.Hidden.ToString()))
return;
node.Tag = info;
node.Text = "文件夹:" + info.Name;
}
string[] fileList = Directory.GetFiles(path);
for (int i = 0; i < fileList.Length; i++)
{
if (File.GetAttributes(fileList[i]).ToString().Contains(FileAttributes.Hidden.ToString()))
continue;
TreeNode node1 = new TreeNode();
node1.Tag = fileList[i];
node1.Text = "文件:" + Path.GetFileName(fileList[i]);
node.Nodes.Add(node1);
List extensionList = new List();//扩展名列表,可自定义复选框扩充
if (cbCSharp.Checked)
extensionList.Add(cbCSharp.Text);
if (cbXaml.Checked)
extensionList.Add(cbXaml.Text);
foreach (string extension in extensionList)
{
if (extension.EndsWith(Path.GetExtension(fileList[i])))
{
analysisFileList.Add(fileList[i]);
node1.ForeColor = Color.Red;
}
}
}
node.Expand();
if (nodeTemp == null)
MyTreeView.Nodes.Add(node);
else
nodeTemp.Nodes.Add(node);
//GetDirectories:获取指定目录中子目录的名称
string[] directoryList = Directory.GetDirectories(path);
for (int i = 0; i < directoryList.Length; i++)
{
LoadDirectory(directoryList[i], node);//递归获取所有文件夹下所有文件
}
}
二、统计
private void btnStart_Click(object sender, EventArgs e)
{
int codeCount = 0;//代码行数
int commentCount = 0;//注释行数
foreach (string file in analysisFileList)
{
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
while (!sr.EndOfStream)
{
string str = sr.ReadLine();
str = str.Trim();
if (str == "" || str.StartsWith("using") || str.StartsWith("namespace"))
continue;
if (str.StartsWith("//"))//这里还需要考虑/* */注释的处理方式
{
commentCount++;
continue;
}
else
{
codeCount++;
if (str.Contains("//"))
commentCount++;
}
}
sr.Close();
fs.Close();
StatisticsInfo info = new StatisticsInfo();
info.fileName = Path.GetFileName(file);
info.codeCount = codeCount;
info.commentCount = commentCount;
infoList.Add(info);
txtAnalysis.Text += info.fileName + " " + codeCount.ToString() + " " + commentCount.ToString() + Environment.NewLine;
}
}
三、导出word
private void btnExportWord_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Word.Application app = null;
Microsoft.Office.Interop.Word.Document doc = null;
try
{
int rows = infoList.Count() + 1;//表格行数加1是为了标题栏
int cols = 3;//表格列数
object oMissing = System.Reflection.Missing.Value;
app = new Microsoft.Office.Interop.Word.Application();//创建word应用程序
doc = app.Documents.Add();//添加一个word文档
//换行添加表格
Microsoft.Office.Interop.Word.Range range = app.Selection.Range;
Microsoft.Office.Interop.Word.Table table = app.Selection.Tables.Add(range, rows, cols, ref oMissing, ref oMissing);
//设置表格的字体大小粗细
table.Range.Font.Size = 10;
table.Range.Font.Bold = 0;
//设置表格标题
int rowIndex = 1;
table.Cell(rowIndex, 1).Range.Text = "文件名";
table.Cell(rowIndex, 2).Range.Text = "代码数";
table.Cell(rowIndex, 3).Range.Text = "注释数";
foreach (var i in infoList)
{
//循环数据创建数据行
rowIndex++;
table.Cell(rowIndex, 1).Range.Text = i.fileName;//文件名
table.Cell(rowIndex, 2).Range.Text=i.codeCount.ToString();//代码数
table.Cell(rowIndex, 3).Range.Text = i.commentCount.ToString();//注释数
//对表格中单元格设置上下居中
table.Cell(rowIndex, 1).VerticalAlignment = Microsoft.Office.Interop.Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(rowIndex, 2).VerticalAlignment = Microsoft.Office.Interop.Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(rowIndex, 3).VerticalAlignment = Microsoft.Office.Interop.Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;
}
//导出到文件
string newFile = System.Windows.Forms.Application.StartupPath+@"/" +DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc";
doc.SaveAs(newFile,
oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing,
oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);
Process.Start(newFile);
}
catch (Exception ex)
{
}
finally
{
if (doc != null)
{
doc.Close();//关闭文档
}
if (app != null)
{
app.Quit();//退出应用程序
}
}
}
四、效果图
主界面:
word表格效果
五、需要完善文件类型以及代码的统计处理方式,目前的统计方式过于简单粗暴,还不能做到精确处理。
六、如想自行完善源码,或直接使用,可在csdn搜索资源:https://download.csdn.net/download/lefuture2/11811599