统计指定目录下Java源代码的总行数
来源:互联网 发布:黑魂34g内存优化 编辑:程序博客网 时间:2024/06/03 00:31
遍历指定文件夹并统计代码行数,和Java关键字频率,降序输出所有结果。
默认统计.java文件,可以自定义统计其他源码。
打算将它整合到自己做的桌面小程序中。
部分输出如下:
代码总行数:11341E:\java\以往习作\KingTetris.java--->行数:419F:\EclipseProject\Test\src\king\countcode\CountCodeLine.java--->行数:340F:\EclipseProject\记事本\src\king\notepad\view\NotepadFrame.java--->行数:332F:\EclipseProject\五子棋\src\guyuanguanli.java--->行数:298F:\EclipseProject\记事本\src\king\notepad\service\TextService.java--->行数:277F:\EclipseProject\简易绘图板\src\King\Test.java--->行数:267
---------Java代码关键字统计:----------关键字:new 出现次数:873关键字:int 出现次数:668关键字:public 出现次数:608关键字:private 出现次数:520关键字:null 出现次数:511关键字:void 出现次数:413关键字:static 出现次数:299关键字:return 出现次数:293关键字:if 出现次数:282关键字:this 出现次数:232关键字:class 出现次数:201关键字:for 出现次数:161关键字:true 出现次数:146关键字:else 出现次数:92关键字:final 出现次数:88关键字:false 出现次数:79关键字:case 出现次数:78关键字:catch 出现次数:68关键字:while 出现次数:67关键字:try 出现次数:63关键字:boolean 出现次数:60关键字:extends 出现次数:56关键字:implements 出现次数:55关键字:throws 出现次数:45关键字:break 出现次数:41关键字:char 出现次数:40关键字:super 出现次数:34关键字:byte 出现次数:32关键字:switch 出现次数:22关键字:double 出现次数:17关键字:abstract 出现次数:16关键字:do 出现次数:15关键字:protected 出现次数:13关键字:synchronized 出现次数:9关键字:long 出现次数:9关键字:finally 出现次数:8关键字:throw 出现次数:8关键字:instanceof 出现次数:7关键字:default 出现次数:6关键字:float 出现次数:2关键字:continue 出现次数:2关键字:package 出现次数:2关键字:transient 出现次数:2关键字:import 出现次数:2关键字:interface 出现次数:2关键字:native 出现次数:2关键字:volatile 出现次数:2关键字:short 出现次数:2关键字:strictfp 出现次数:1关键字:enum 出现次数:1关键字:const 出现次数:1关键字:goto 出现次数:1关键字:assert 出现次数:1
源码:
package king.countcode;import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Set;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * 统计指定目录下Java文件的总行数、关键字频率 * */public class CountCodeLine { private int count = 0; // 所有需要遍历的文件 private List<File> allFile = new LinkedList<File>(); // 所有遍历结果 private Map<String, Integer> allResult = new HashMap<String, Integer>(); // 排序后的所有遍历结果 private List<Map.Entry<String, Integer>> allSortedResult = new LinkedList<Map.Entry<String, Integer>>(); // 需要检查的文件后缀,默认添加.java private List<String> allSuffix = new LinkedList<String>(); private static final String JAVA_SUFFIX = ".java"; //提取单词的正则表达式 private Pattern p = Pattern.compile("(?<=\\W)\\w+(?=\\W)"); //用于计数 private Keywords countKeyword = new Keywords(); public CountCodeLine(){ addSuffix(JAVA_SUFFIX); } public static void main(String[] args) { CountCodeLine count = new CountCodeLine(); // 添加需要检查的文件或文件夹 count.addPath("E:\\java"); count.addPath("F:\\EclipseProject"); // // 遍历C盘之外所有硬盘// // 由于文件太多,全部遍历需要很久才能出结果,一般不建议// File[] roots = File.listRoots();// for(int i = 0; i < roots.length; i++){// // C盘某些文件夹无权限进入,会报错,故剔除// if (!roots[i].getAbsolutePath().toLowerCase().startsWith("c:")){// count.addPath(roots[i].getAbsolutePath());// }// } // 检查并返回统计 总行数 System.out.println("代码总行数:" + count.execute()); // 输出降序排列的总结果 for(Map.Entry<String, Integer> entry : count.getAllSortedResult()){ System.out.println(entry.getKey() + "--->行数:" + entry.getValue()); } //输出所有Java文件中的关键字频率统计 // 如果想统计单个文件,请在上方addPath()仅输入单个文件的绝对地址 System.out.println(); System.out.println("---------Java代码关键字统计:----------"); System.out.println(count.getUsedKeywordFrequency()); } /* * 添加需要检查的文件或文件夹 */ public void addPath(String path){ allFile.add(new File(path)); } /* * 添加需要检查的后缀名 * 如果要用来统计其他后缀名的文件,请先clear() */ public void addSuffix(String suffix){ suffix = suffix.toLowerCase(); //全转小写 if (!suffix.startsWith(".")) suffix = "." + suffix; allSuffix.add(suffix); } /* * 开始遍历 */ public int execute(){ for(File file : allFile){ checkFile(file); } // 排序所有结果 sortAllResult(); return getCount(); } /* * 获取当前count值 */ public int getCount(){ return count; } /* * 返回详细的结果 * 文件名-代码行数映射的Set<Map.Entry<String, Integer>> */ public Set<Map.Entry<String, Integer>> getAllResult(){ return allResult.entrySet(); } /** * 返回所有排序后的结果 */ public List<Map.Entry<String, Integer>> getAllSortedResult(){ return new LinkedList<Map.Entry<String, Integer>>(allSortedResult); } /** * 返回关键字频率的统计结果 * @return */ public String getUsedKeywordFrequency(){ return countKeyword.getUsedKeywordFrequency(); } /* * 清空所有内容,以便开始全新的查找 */ public void clear(){ count = 0; allFile.clear(); allResult.clear(); allSortedResult.clear(); allSuffix.clear(); } /* * 遍历文件夹 */ private void checkFile(File file){ if (file.isDirectory()){ File[] files = file.listFiles(); for(File f : files){ checkFile(f); } } else if (checkSuffix(file)){ countLine(file); }// // 下面是循环方法,当递归溢出时,可改用循环// Stack<File> stack = new Stack<File>();// stack.push(file);// while(!stack.isEmpty()){// File tmp = stack.pop(); // if (tmp.isDirectory()){// File[] files = tmp.listFiles();// for (File f : files){// stack.push(f);// }// } else if (checkSuffix(tmp)){// countLine(tmp);// }// } } /** * 检查后缀名 */ private boolean checkSuffix(File file){ String fileName = file.getName().toLowerCase(); for(String suffix : allSuffix){ if (fileName.endsWith(suffix)) return true; } return false; } /* * 统计Java文件的行数 */ private void countLine(File file){ try (BufferedReader input = new BufferedReader(new FileReader(file))){ String str = null; int tmpCount = 0; while ((str = input.readLine()) != null){ // 检查这一行里的每一个单词 Matcher m = p.matcher(str); while(m.find()){ // 判断是否Java关键字 countKeyword.checkWord(m.group()); } tmpCount++; } count += tmpCount; allResult.put(file.getAbsolutePath(), tmpCount); //保存到集合中 } catch (IOException e) { e.printStackTrace(); } } /** * 排序所有统计结果 * 降序 */ private void sortAllResult(){ allSortedResult.addAll(allResult.entrySet()); Collections.sort(allSortedResult, new Comparator<Map.Entry<String, Integer>>(){ @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2){ int value1 = o1.getValue(); int value2 = o2.getValue(); if (value1 == value2) return 0; return value1 > value2 ? -1 : 1; } }); }}//关键字集合,用于计数class Keywords { // 所有关键字 private Map<String, Integer> keywords = new HashMap<String, Integer>(); //构造器 public Keywords(){ reset(); } //复位清零 public void reset(){ for(Keyword k : Keyword.values()){ //从枚举类获取关键字 keywords.put(k.getKeyword(), 0); } } //检测一个单词是否关键字,如果是,就让对应的关键字频数加1 public void checkWord(String word){ if (keywords.keySet().contains(word)){ keywords.put(word, keywords.get(word) + 1); } } //返回统计结果 public String getUsedKeywordFrequency(){ StringBuilder result = new StringBuilder(); StringBuilder tmp = new StringBuilder(); //按频数即value值排序 //就算用TreeMap也只能对key排序,下面用自己写的比较器排序 //继承Comparator接口改改名compare方法后,TreeSet会认为compare结果为0的两个元素是同一个元素,故不用TreeSet List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(keywords.entrySet()); Collections.sort(list, new MyMapEntryComparator()); for(Map.Entry<String, Integer> entry : list){ if (entry.getValue() != 0){ tmp.setLength(0); tmp.append("关键字:").append(entry.getKey()).append("出现次数:").append(entry.getValue()); result.append(typeset(tmp)).append("\n"); } } return result.toString(); } /** * 将字符串排版再返回,如下输出不整齐 * 关键字:null 出现次数:1 * 关键字:implements 出现次数:1 * 控制“关键字”和“出现次数”之间的空格, * 将来可能改变输出的汉字,故下面用正则式考虑更广泛的情况 * @param StringBuilder * @return String */ private String typeset(StringBuilder sb){ StringBuilder result = new StringBuilder(); int blank = 15; //不同组汉字之间的空白 int index = 0, length = 0, differ; //找出右边不是紧邻汉字的汉字,向后数十五个空 Pattern p = Pattern.compile("(?<![一-龥])[一-龥]+(?![一-龥])"); Matcher m = p.matcher(sb); while(m.find()){ //find()后移一位 result.append(sb.substring(index, m.start())); if((differ = blank -(m.start() - index - length)) > 0 && m.start() != 0){ while(differ-- > 0){ result.append(" "); } } index = m.start(); length = m.group().length(); } //如果后面中文,则把剩下的全接上去 result.append(sb.substring(index)); return result.toString(); } //比较用的Comparator,只在这时用到,故写成内部类 private class MyMapEntryComparator implements Comparator<Map.Entry<String, Integer>>{ @Override public int compare(Map.Entry<String, Integer> m1, Map.Entry<String, Integer> m2){ return -(m1.getValue() - m2.getValue()); } } }//所有关键字,枚举类,仅用于存储enum Keyword{ ABSTRACT("abstract"), ASSERT("assert"), BOOLEAN("boolean"), BREAK("break") , BYTE("byte"), CASE("case"), CATCH("catch"), CHAR("char"), CLASS("class") , CONST("const"), CONTINUE("continue"), DEFAULT("default"), DO("do"), DOUBLE("double") , ELSE("else"), ENUM("enum"), EXTENDS("extends"), FALSE("false"), FINAL("final") , FINALLY("finally"), FLOAT("float"), FOR("for"), GOTO("goto"), IF("if") , IMPLEMENTS("implements"), IMPORT("import"), INSTANCEOF("instanceof"), INT("int") , INTERFACE("interface"), LONG("long"), NATIVE("native"), NEW("new"), NULL("null") , PACKAGE("package"), PRIVATE("private"), PROTECTED("protected"), PUBLIC("public") , RETURN("return"), SHORT("short"), STATIC("static"), STRICTFP("strictfp") , SUPER("super"), SWITCH("switch"), SYNCHRONIZED("synchronized"), THIS("this") , THROW("throw"), THROWS("throws"), TRANSIENT("transient"), TRY("try"), TRUE("true") , VOID("void"), VOLATILE("volatile"), WHILE("while"); private String keyword; //构造器 private Keyword(String keyword){ this.keyword = keyword; } //获取keyword public String getKeyword() { return keyword; }}
0 0
- 统计指定目录下Java源代码的总行数
- 统计一个目录下所有普通文件的总行数
- 获取指定目录下所有csv文件的总行数
- linux下如何统计一个目录下的文件个数以及代码总行数的命令
- linux下如何统计一个目录下的文件个数以及代码总行数的命令
- linux下如何统计一个目录下的文件个数以及代码总行数的命令
- Mac下如何统计一个目录下所有代码文件的总行数
- 如何统计一个目录下的文件个数以及代码总行数的命令
- 输出该目录下指定类型文件(.cs, .java)的个数、文件的总行数、空行数、注释行数、代码行数
- 输出该目录下指定类型文件(.cs, .java)的个数、文件的总行数、空行数、注释行数、代码行数
- 课程实验一:目标一:输出该目录下指定类型文件(.cs, .java)的个数、文件的总行数、空行数、注释行数、代码行数
- linux下如何统计一个目录下的文件个数以及代码总行数的命令
- 统计源代码文件的总行数、空行数、注释行数、代码行数
- iOS 统计项目的总行数
- 统计Xcode代码总行数的方法
- 统计代码总行数
- Xcode统计总行数
- java 查找目录下指定文件名的文件源代码
- Ubuntu 安装mysql和简单操作
- 【数据库-MySql】MYSQL 语句
- Oracle 把数据导入不同的表空间
- 1.第一个C程序
- Git 常用命令速查表(图文+表格)
- 统计指定目录下Java源代码的总行数
- 织梦DedeCMS防黑客入侵或DDOS攻击的方法
- spring mvc interceptor 示例
- 宽窄字符串函数对应关系
- struts2实现文件批量下载
- [谈seo优化] 实战seo教程2:我是怎么将“seo论坛”在50天内优化到百度前三
- Java 批量插入数据库(MySQL)数据
- 解决Eclipse和myeclipse在进行 html,jsp等 页面编辑时,自动格式化变丑的问题
- web前段设计之痛:手机浏览器和pc浏览器的width:100%的自适应问题 .