最近正好需要统计下某项目代码行数,然后就找代码行数统计工具。以前找到过一个正则表达式,但是只有在VS2010下有用,VS2012和VS2013下的统计就不好使了。

接着搜索了一下代码行数统计绿色工具免费版,看到花花绿绿的浮动窗口和卧虎藏龙的下载链接,感觉非常令人生厌,而且,有些国产软件下载总是让你一不小心就中毒,所以最后还是放弃了下载。

当然,你知道,这点简单小功能,对于已经习惯自己搬砖搞定一切的码农,实在没有必要再费时间搜来搜去,而且那首歌唱得好,“Let it go,let it go...The code doesn‘t bother me anyway.”,所谓求人不如求己是也。

抽空自己写了这个代码行数分析winform工具,目前测试通过支持的语言有C#、Java、SQL、JavaScript和Python,共享出来,希望对你有帮助。

软件界面:

一、程序简单分析

统计分析代码行数,需要分析源文件。这里的程序选择简单的打开源文件的方法,但是读取内容不是一下子全部读完,而是一行一行读取,读取后,需要按统计条件分析并计数。

统计条件抽象如下:

using System;

namespace PowerCodeCalculator.Model
{
/// <summary>
/// 代码统计条件
/// </summary>
[Serializable]
public sealed class CodeStatisticCondition
{
/// <summary>
/// 代码目录 绝对路径 形如:D:\PowerCode
/// </summary>
public string CodeDirectory { get; set; } /// <summary>
/// 统计的代码类型 通常为.cs代码文件
/// </summary>
public string FileTypeFilter { get; set; } /// <summary>
/// 忽略统计的代码文件 如VS自动生成的.designer.cs文件等 多个以逗号,分隔
/// </summary>
public string IgnoreFileType { get; set; } /// <summary>
/// 是否统计大括号{或}
/// </summary>
public bool IsCalcBrace { get; set; } /// <summary>
/// 是否统计空行行数
/// </summary>
public bool IsCalcEmptyLine { get; set; } /// <summary>
/// 是否统计注释行数
/// </summary>
public bool IsCalcComment { get; set; } /// <summary>
/// 是否启用多线程统计
/// </summary>
public bool IsEnableMultiThread { get; set; }
}
}

CodeStatisticCondition

代码源文件信息CodeInfo抽象如下:

using System;

namespace PowerCodeCalculator.Model
{
/// <summary>
/// 代码信息实体
/// </summary>
[Serializable]
public sealed class CodeInfo
{
/// <summary>
/// 文件名绝对路径 形如:c:\Program.cs
/// </summary>
public String FilePath { get; set; } /// <summary>
/// 代码行数
/// </summary>
public Int64 LineCount { get; set; } /// <summary>
/// 代码字符数
/// </summary>
public Int64 CharCount { get; set; }
}
}

CodeInfo

返回的源文件统计信息CodeStatisticInfo抽象如下:

using System;
using System.Collections.Generic;
using System.Collections.Concurrent; namespace PowerCodeCalculator.Model
{
/// <summary>
/// 代码统计结果信息实体
/// </summary>
[Serializable]
public sealed class CodeStatisticInfo
{ /// <summary>
/// 是否成功
/// </summary>
public bool IsOK { get; set; } /// <summary>
/// 代码总行数
/// </summary>
public Int64 TotalCount { get; set; } /// <summary>
/// 代码字符总数
/// </summary>
public Int64 TotalCharCount { get; set; } /// <summary>
/// 代码信息列表
/// </summary>
public List<CodeInfo> CodeInfoList { get; set; } /// <summary>
/// 统计输出信息
/// </summary>
public String OutPutInfo { get; set; }
}
}

CodeStatisticInfo

主要统计的业务逻辑在CodeCounterService的Calc方法中:

public static CodeStatisticInfo Calc(CodeStatisticCondition condition)
{
//1、验证参数
var statResult = CheckCondition(condition);
if (statResult.IsOK == false)
{
return statResult;
} //2、递归获取所有代码目录
var dirList = GetFileDir(condition.CodeDirectory); //3、以目录为单位进行遍历统计
try
{
if (condition.IsEnableMultiThread == false) //单线程统计
{
foreach (var dir in dirList)
{
var innerCodeInfoList = GetCodeInfoList(dir, condition);
statResult.CodeInfoList.AddRange(innerCodeInfoList);
}
}
else //多线程统计 待统计代码目录较多,文件较大或者个人PC配置渣渣的情况下请慎用
{
var taskCnt = ; //并发任务数
var dictDir = GetGroupDir(taskCnt, dirList);
var taskFactory = new TaskFactory();
foreach (var kv in dictDir)
{
PowerLogger.AppendLog("任务【{0}】,并发执行{1}个目录的代码统计", kv.Key, kv.Value.Count);
var listTask = new List<Task<IList<CodeInfo>>>();
foreach (var item in kv.Value)
{
var notifyTask = taskFactory.StartNew<IList<CodeInfo>>
(
() => { return GetCodeInfoList(item, condition); }
); listTask.Add(notifyTask);
} Task.WaitAll(listTask.ToArray()); //等待一批任务并行执行完成 foreach (var tmpTask in listTask)
{
statResult.CodeInfoList.AddRange(tmpTask.Result);
}
}
}
}
catch (Exception ex)
{
statResult.IsOK = false;
statResult.OutPutInfo = string.Format("统计代码发生异常:{0}", ex);
}
if (statResult.IsOK == false)
{
return statResult;
} //4、统计代码总行数及输出
statResult.TotalCount = statResult.CodeInfoList.Sum(x => x.LineCount);
statResult.TotalCharCount = statResult.CodeInfoList.Sum(x => x.CharCount); var sb = new StringBuilder();
sb.AppendFormat("代码总行数:{0}", statResult.TotalCount);
sb.AppendLine();
sb.AppendFormat("代码总字符数:{0}", statResult.TotalCharCount);
sb.AppendLine(); if (statResult.CodeInfoList.Any())
{
sb.Append("代码行数统计明细:");
sb.AppendLine();
}
else
{
sb.Append("没有匹配的代码文件");
}
foreach (var codeInfo in statResult.CodeInfoList)
{
sb.Append(codeInfo.FilePath);
sb.AppendLine();
sb.AppendFormat("【代码行数】:{0}", codeInfo.LineCount);
sb.AppendLine();
sb.AppendFormat("【代码字符数】:{0}", codeInfo.CharCount); sb.AppendLine();
sb.AppendLine();
} statResult.OutPutInfo = sb.ToString(); return statResult;
}

Calc

二、存在的主要不足和缺点

1、不同语言统计支持没有经过充分测试

目前这个小程序仅仅验证了自己经常使用的几种开发语言,其他语言未验证是否通过。

2、多线程统计支持不好

代码中,我想用Task提升性能,目前测试下来,多线程比单线程耗时更久,非常不友好。本来计划使用多线程技术打开文件并行分析每个文件的代码行数,毕竟,IO和计算密集型程序在多线程下应该能够发挥优势。但是看到根据目录并发分析统计代码效果并不好,所以我就直接放弃了多文件同时分析的实现。

3、统计数据不精确

代码行数统计并不完全准确,“统计”的时候,可能某项目下已经无效的代码也加入了统计。还有就是注释,不同语言的注释解析是个难题。再比如说压缩后的js文件,这个也会造成解析统计的不准确。

demo地址:PowerCodeCalculator

可执行文件下载:PowerCodeCalculator.exe

Sharing A Powerful Tool For Calculate Code Lines的更多相关文章

  1. Sharing A Powerful Tool For Application Auto Monitor

    本文分享的这个应用监控小工具,本来是我在五年多以前开发实现的windows服务监控的一个windows服务.听上去比较拗口吧,是的,这个应用一开始就是个监控windows服务的windows服务. 记 ...

  2. [tool] Visual Studio Code python配置

    语言设置 安装中文插件即可成为中文 选择一个Python解释器 Python是一种解释型语言,为了运行Python代码并获取Python IntelliSense,您必须告诉VS Code使用哪个解释 ...

  3. 安装使用Entity Framework Power Tool Bate4 (Code First)从已建好的数据自动生成项目中的对应Model(新手贴,望各位大侠给予指点)

    从开始学习使用MVC以后,同时也开始接触EF,很多原理都不是太懂,只知道安装了EF以后,点击哪里可以生成数据库对应的Model,不用再自己手写Model.这里记录的就是如何从已建立好的数据库生成项目代 ...

  4. 计算机视觉code与软件

    Research Code A rational methodology for lossy compression - REWIC is a software-based implementatio ...

  5. Code Project精彩系列(转)

    Code Project精彩系列(转)   Code Project精彩系列(转)   Applications Crafting a C# forms Editor From scratch htt ...

  6. Code Complete阅读笔记(二)

    2015-03-06   328   Unusual Data Types    ——You can carry this technique to extremes,putting all the ...

  7. (2)入门指南——(7)添加jquery代码(Adding our jQuery code)

    Our custom code will go in the second, currently empty, JavaScript file which we included from the H ...

  8. source code analyzer 功能强大的C/C++源代码分析软件 Celerity CRACK 破解版

    特色 迅捷是一个功能强大的C/C++源代码分析软件.可以处理数百万行的源程序代码.支持标准及K&R风格的C/C++.对每一个打开的源代码工程,通过建立一个包含丰富交叉引用关系的数据库,显示其所 ...

  9. Top 40 Static Code Analysis Tools

    https://www.softwaretestinghelp.com/tools/top-40-static-code-analysis-tools/ In this article, I have ...

随机推荐

  1. The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties

    出现这个错误提示可以用 DbFunctions.TruncateTime 将Linq中entity的DateTime转化一下再使用,如下所示: var anyCalls = _db.CallLogs. ...

  2. Java集合框架练习-计算表达式的值

    最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...

  3. echarts之tooltip

    tooltip:提示框,鼠标悬浮交互时的信息提示. 当trigger为'item'时 tooltip : { trigger: 'item' }, 当trigger为'axis'时 tooltip : ...

  4. 【C++设计模式】单件类与DCLP(Double Check Lock Pattern)的风险

    [单件类] 保证只能有一个实例化对象,并提供全局的访问入口. [设计注意事项] 1.阻止所有实例化的方法: private 修饰构造函数,赋值构造函数,赋值拷贝函数. 2.定义单实例化对象的方法: a ...

  5. docker学习之二镜像创建

    继上一篇docker入门之后写一点使用的经验. 通过命令:docker run -it REPOSITORY或IMAGE ID   注:-it后面跟的字段可以通过下面指令获得 创建运行的容器,会进入一 ...

  6. 用Barcode生成条形码图片

    使用第三方类库:BarcodeLib.dll private BitmapImage GenerateBarcodeBitmap(string visitId) { BarcodeLib.Barcod ...

  7. NAIPC-2016

    A. Fancy Antiques 爆搜+剪枝. #include <bits/stdc++.h> using namespace std ; typedef pair < int ...

  8. 【BZOJ3172】[Tjoi2013]单词 AC自动机

    [BZOJ3172][Tjoi2013]单词 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input ...

  9. 【SRM】518 Nim

    题意 \(K(1 \le K \le 10^9)\)堆石子,每堆石子个数不超过\(L(2 \le 50000)\),问Nim游戏中先手必败局面的数量,答案对\(10^9+7\)取模. 分析 容易得到\ ...

  10. Java 实现HTML富文本导出至word完美解决方案

    一. 问题的提出 最近用java开发一个科技项目信息管理系统,里面有一个根据项目申请书的模板填写项目申报信息的功能,有一个科技项目申请书word导出功能. 已有的实现方式:采用标准的jsp模板输出实现 ...