• 源程序数 demo


    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    public class CodeLineCount {
    
        /**
         * 只统计这个集合约定的文件名后缀的代码量, 其他后缀全部视为无效文件 -- it up to you
         */
        private static final Set<String> VALID_SUFFIX_SET = new HashSet<>();
        static {
            VALID_SUFFIX_SET.add(".c");
            VALID_SUFFIX_SET.add(".h");
            //.java文件为需要统计代码的文件
            VALID_SUFFIX_SET.add(".java");
            //.xml文件为需要统计代码的文件
            // VALID_SUFFIX_SET.add(".xml");
            //.properties文件为需要统计代码的文件
            // VALID_SUFFIX_SET.add(".properties");
        }
    
        /**
         * 需要过滤掉的目录, 例如测试用例代码所在目录
         */
        private static final Set<String> EXCLUDE_DIRECTORY_SET = new HashSet<>();
        static {
            // 过滤掉/src/test目录下的文件(即测试用例相关代码)
            EXCLUDE_DIRECTORY_SET.add("src"+File.separator+"test");
            EXCLUDE_DIRECTORY_SET.add("target");
        }
    
        /**
         * 是否需要输出文件或者目录过滤与否的信息, 如果需要输出, 还会输出文件或者目标被过滤的原因: 无效文件or无效目录
         */
        private static final boolean FILE_FILTER_INFO = true;
    
        /**
         * 是否过滤掉源码中的注释
         */
        private static final boolean FILTER_COMMENT = true;
    
        public static void main(String[] args) throws Exception{
            String target ;
            List<String> projectNameList = new ArrayList<>();
            projectNameList.add("international");
            for(String projectName:projectNameList) {
                target = "D:\ccii3\ccii\" + projectName;
                System.out.println(target + "(" + projectName + ")总行数:" + lineCount(target));
            }
        }
    
        /**
         * 统计文件或者目录下所有文件总行数
         * @param target 文件路径或者目录路径
         * @return 文件或者目录下所有文件总行数
         * @throws Exception
         */
        private static int lineCount(String target) throws Exception{
            // 先判断是文件还是目录
            File origin = new File(target);
            if (origin.isFile()){
                return fileCount(origin);
            }else{
                // 如果是目录要遍历
                return directoryCount(origin);
            }
        }
    
        private static int directoryCount(File dir) throws Exception {
            int sum = 0;
    
            File[] files = dir.listFiles();
            if (files==null){
                throw new IllegalArgumentException("无效的目录:"+dir.getCanonicalPath());
            }
    
            for (File file:files){
                if (file.isFile()){
                    sum += fileCount(file);
                }else{
                    sum += directoryCount(file);
                }
            }
            return sum;
        }
    
        /**
         * 全路径指定的文件所在目录是否是需要exclude的目录
         * @param path 文件的全路径
         * @return 文件所在目录是否是需要exclude的目录
         */
        private static boolean invalidDirectory(String path){
            for (String dir: EXCLUDE_DIRECTORY_SET){
                if (path.contains(dir)){
                    return true;
                }
            }
    
            return false;
        }
    
        /**
         * 全路径指定的文件后缀是否是约定的合法文件后缀(VALID_SUFFIX_SET指定)
         * @param path 文件的全路径
         * @return 是否是有效的文件
         */
        private static boolean validFile(String path){
            for (String suffix: VALID_SUFFIX_SET){
                if (path.endsWith(suffix)){
                    return true;
                }
            }
            return false;
        }
    
        /**
         * 文件中内容行数统计
         * @param file 文件
         * @return 文件中内容总行数
         * @throws Exception
         */
        private static int fileCount(File file) throws Exception {
    
            String path = file.getCanonicalPath();
    
            boolean validFile = validFile(path);
            boolean invalidDirectory = invalidDirectory(path);
            if (!validFile || invalidDirectory){
                if (FILE_FILTER_INFO) {
                    System.out.println("需要过滤的文件: " + path + ", " +(validFile?"无效目录":"无效文件"));
                }
                return 0;
            }
            if (FILE_FILTER_INFO) {
                System.out.println("不需过滤的文件: " + path);
            }
    
            BufferedReader reader = new BufferedReader(new FileReader(file));
            int count = 0;
    
            String line;
            // readLine结果为null表示读到文件末尾了
            while((line = reader.readLine())!=null){
                // 行内容不为空的话, 如果需要过滤注释且不是注释代码行才自增, 如果不需要过滤注释代码行也自增;
                if (FILTER_COMMENT) {
                    if (!isCommentLine(line)) {
                        ++count;
                    }
                }else{
                    //
                    ++count;
                }
            }
            return count;
        }
    
        /**
         * 判断这一行内容是否是注释: 以/或者*开头就认为是注释
         * @param line 一行内容
         * @return 是注释则返回true, 否则返回false
         */
        private static boolean isCommentLine(String line){
            String content = line.trim();
            if (content.startsWith("/")
                    || content.startsWith("*")){
                System.out.println("这一行内容是注释: "+line);
                return true;
            }
            return false;
        }
    }
  • 相关阅读:
    SVN的具体使用方法介绍(安装以及操作)
    谈谈敏捷开发
    008.MVC与数据库的交互
    001.MVC基本概述
    WebApi接口测试工具
    014.存储过程(sql实例)
    我们为什么需要DTO(数据传输对象)
    ASP.NET使用WebApi接口实现与Android客户端的交互(图片或字符串的接收与回传)
    面试题库[2]
    关于单例模式getInstance()的使用
  • 原文地址:https://www.cnblogs.com/-mzh/p/12802228.html
Copyright © 2020-2023  润新知