统计代码行数。。

来源:互联网 发布:犀牛软件模型免费下载 编辑:程序博客网 时间:2024/06/10 23:32

话说之前直接用eclipse的代码行数统计,但是只能统计文件所有行数,不能统计具体的代码,我按照VC的那个统计行数的插件仿着写了个。。

统计指定扩展名下的总行数、纯代码行数、纯注释行数、代码混合注释行数、空行数以及非空行数。

下面是计算代码,可以控制台调用:

Code:
  1. import java.util.ArrayList;   
  2. import java.util.List;   
  3. import java.util.Scanner;   
  4. import java.io.File;   
  5. import java.io.FileNotFoundException;   
  6.     
  7. /**  
  8. *      统计行数  
  9. *      @author YOYO  
  10. */  
  11. public class LineCounter   
  12. {   
  13.     
  14.         /** 搜索的文件扩展名 */  
  15.         public List<String> fileExts = new ArrayList<String>();   
  16.     
  17.         /** 纯代码行数 */  
  18.         private int codeLines = 0;   
  19.     
  20.         /** 代码与注释同一行的行数 */  
  21.         private int codeWithCommentLines = 0;   
  22.     
  23.         /** 注释行数 */  
  24.         private int commentLines = 0;   
  25.     
  26.         /** 空白行数 */  
  27.         private int blankLines = 0;   
  28.           
  29.         /**  
  30.          * 搜索的扩展名  
  31.          */  
  32.         public void setFileExts(String... exts) {   
  33.                 fileExts.clear();   
  34.                 for (String ext: exts) {   
  35.                         fileExts.add(ext);   
  36.                 }   
  37.         }   
  38.           
  39.         /**  
  40.          *      总行数  
  41.          */  
  42.         public int getTotalLines() {   
  43.                 return codeLines + codeWithCommentLines + commentLines + blankLines;   
  44.         }   
  45.           
  46.         /**  
  47.          *      代码行数  
  48.          */  
  49.         public int getCodeLines() {   
  50.                 return codeLines;   
  51.         }   
  52.           
  53.         /**  
  54.          *      注释行数  
  55.          */  
  56.         public int getCommentLines() {   
  57.                 return commentLines;   
  58.         }   
  59.           
  60.         /**  
  61.          *      代码混合注释行数  
  62.          */  
  63.         public int getCodeWithCommentsLines() {   
  64.                 return codeWithCommentLines;   
  65.         }   
  66.           
  67.         /**  
  68.          *      空行数  
  69.          */  
  70.         public int getBlankLines() {   
  71.                 return blankLines;   
  72.         }   
  73.           
  74.         /**  
  75.          *      非空行数  
  76.          */  
  77.         public int getNonBlankLines() {   
  78.                 return getTotalLines() - blankLines;   
  79.         }   
  80.     
  81.         /**  
  82.          *      打印结果  
  83.          */  
  84.         public void printResult() {   
  85.                 int totalLines = codeLines + codeWithCommentLines + commentLines + blankLines;   
  86.                 int nonblankLines = totalLines - blankLines;   
  87.     
  88.                 System.out.println("=========================================");   
  89.                 System.out.println("Total Lines  : " + totalLines);   
  90.                 System.out.println("Only Codes    : " + codeLines);   
  91.                 System.out.println("Only Comment                : " + commentLines);   
  92.                 System.out.println("Code With Comments  : " + codeWithCommentLines);   
  93.                 System.out.println("Blank Lines  : " + blankLines);   
  94.                 System.out.println("Non-Blank Lines          : " + nonblankLines);   
  95.                 System.out.println("=========================================");   
  96.         }   
  97.     
  98.         /**  
  99.          *      统计行数  
  100.          *      @param folder 项目路径  
  101.          */  
  102.         public void count(String folder) {   
  103.                 File file = new File(folder);   
  104.                 if (null == file) {   
  105.                         return;   
  106.                 }   
  107.     
  108.                 //      目录 则遍历子文件与文件夹   
  109.                 if (file.isDirectory()) {   
  110.                         for (String fileName: file.list()) {   
  111.                                 count(file.getPath() + "//" + fileName);   
  112.                         }   
  113.                 } else {   
  114.                         //      检查是否需要统计的文件类型   
  115.                         boolean flag = false;   
  116.                         for (String ext: fileExts) {   
  117.                                 if (folder.endsWith(ext)) {   
  118.                                         flag = true;   
  119.                                         break;   
  120.                                 }   
  121.                         }   
  122.                         if (!flag) {   
  123.                                 return;   
  124.                         }   
  125.     
  126.                         //      统计文件行数   
  127.                         try {   
  128.                                 Scanner scanner = new Scanner(file);   
  129.                                 String line = null;   
  130.                                 boolean isComment = false;   
  131.     
  132.                                 while (scanner.hasNext()) {   
  133.                                         line = scanner.nextLine();   
  134.                                           
  135.                                         //      如果已经有注释开头   
  136.                                         if (isComment) {   
  137.                                                 int pos = exist(line, "*/");   
  138.                                                 if (pos != -1) {   
  139.                                                         isComment = false;   
  140.     
  141.                                                         line = line.substring(0, pos).trim();   
  142.     
  143.                                                         //      以*/结尾的为纯注释句   
  144.                                                         if (line.length() == 0) {   
  145.                                                                 ++commentLines;   
  146.                                                                 continue;   
  147.                                                         }   
  148.     
  149.                                                         //      同时包含/*的,判断最后一个位置   
  150.                                                         pos = exist(line, "/*");   
  151.                                                         if (pos != -1) {   
  152.                                                                 if (existLast(line, "/*") > existLast(line, "*/"))   
  153.                                                                 {   
  154.                                                                         //      如果最后是/* 则依然在注释状态   
  155.                                                                         isComment = true;   
  156.                                                                 } else {   
  157.                                                                         isComment = false;   
  158.                                                                 }   
  159.     
  160.                                                                 //      判断中间是否夹杂代码   
  161.                                                                 if (hasCodes(line)) {   
  162.                                                                         ++codeWithCommentLines;   
  163.                                                                 } else {   
  164.                                                                         ++commentLines;   
  165.                                                                 }   
  166.     
  167.                                                         } else {   
  168.                                                         //      不包含/*且*/之后还有其他字符,则是代码混合注释   
  169.                                                                 ++codeWithCommentLines;   
  170.                                                         }   
  171.                                                 } else {   
  172.                                                         //      不包含*/为纯注释句   
  173.                                                         ++commentLines;   
  174.                                                 }   
  175.     
  176.                                                 continue;   
  177.                                         }   
  178.                                           
  179.                                         int pos = exist(line, "//");   
  180.                                         if (pos != -1) {   
  181.                                                 if (line.trim().startsWith("//")) {   
  182.                                                         //      以//打头,纯注释   
  183.                                                         ++commentLines;   
  184.                                                 } else {   
  185.                                                         //      并非//打头,代码混合注释   
  186.                                                         ++codeWithCommentLines;   
  187.                                                 }   
  188.                                                 continue;   
  189.                                         }   
  190.     
  191.                                         //      如果包含   
  192.                                         pos = exist(line, "/*");   
  193.                                         if (pos != -1) {   
  194.                                                 //      同时包含*/的,判断最后一个位置   
  195.                                                 pos = exist(line, "*/");   
  196.                                                 if (pos != -1) {   
  197.                                                         if (existLast(line, "/*") > existLast(line, "*/")) {   
  198.                                                                 //      如果最后是/* 则依然在注释状态   
  199.                                                                 isComment = true;   
  200.                                                         } else {   
  201.                                                                 isComment = false;   
  202.                                                         }   
  203.     
  204.                                                         //      判断中间是否夹杂代码   
  205.                                                         if (hasCodes(line)) {   
  206.                                                                 ++codeWithCommentLines;   
  207.                                                         } else {   
  208.                                                                 ++commentLines;   
  209.                                                         }   
  210.     
  211.                                                 } else {   
  212.                                                         isComment = true;   
  213.                                                         ++commentLines;   
  214.                                                 }   
  215.     
  216.                                                 continue;   
  217.                                         }   
  218.     
  219.                                         //      空行   
  220.                                         if (line.trim().length() == 0) {   
  221.                                                 ++blankLines;   
  222.                                                 continue;   
  223.                                         }   
  224.                                           
  225.                                         //      不包含//,则是纯代码   
  226.                                         ++codeLines;   
  227.                                 }   
  228.                         }   
  229.                         catch (FileNotFoundException e) {   
  230.                                 e.printStackTrace();   
  231.                         }   
  232.                 }   
  233.         }   
  234.     
  235.         private int exist(String line, String substr) {   
  236.                 int len = 0;   
  237.                 while (true) {   
  238.                         if (line.length() < len) {   
  239.                                 return -1;   
  240.                         }   
  241.                           
  242.                         String str = line.substring(len);   
  243.                         if (!str.contains(substr)) {   
  244.                                 return -1;   
  245.                         }   
  246.     
  247.                         str = str.substring(0, str.indexOf(substr));   
  248.                           
  249.                         int t = 0;   
  250.                         for (int i = 0; i < str.length(); ++i) {   
  251.                                 if (str.charAt(i) == '"' && (i == 0 || str.charAt(i - 1) != '//')) {   
  252.                                         ++t;   
  253.                                 }   
  254.                         }   
  255.                         if (t % 2 == 0) {   
  256.                                 return len + str.length();   
  257.                         }   
  258.                         len = str.length() + 1;   
  259.                 }   
  260.         }   
  261.     
  262.         private int existLast(String line, String substr) {   
  263.                 int len = line.length();   
  264.                 while (true) {   
  265.                         String str = line.substring(0, len);   
  266.                         if (!str.contains(substr)) {   
  267.                                 return -1;   
  268.                         }   
  269.     
  270.                         str = str.substring(0, str.lastIndexOf(substr));   
  271.                         int t = 0;   
  272.                         for (int i = 0; i < str.length(); ++i) {   
  273.                                 if (str.charAt(i) == '"') {   
  274.                                         ++t;   
  275.                                 }   
  276.                         }   
  277.                         if (t % 2 == 0) {   
  278.                                 return str.length();   
  279.                         }   
  280.                         len = str.length() - 1;   
  281.                 }   
  282.         }   
  283.     
  284.         private boolean hasCodes(String line) {   
  285.                 if (line.length() == 0) {   
  286.                         return false;   
  287.                 }   
  288.                   
  289.                 return false;   
  290.         }   
  291.     
  292.         public static void main(String[] args)   
  293.         {   
  294.                 String folder = null;   
  295.     
  296.                 if (args.length == 0) {   
  297.                         System.out.print("Input Your Project Directory >> ");   
  298.                         Scanner scanner = new Scanner(System.in);   
  299.                         folder = scanner.nextLine();   
  300.                 } else {   
  301.                         folder = args[0];   
  302.                 }   
  303.     
  304.                 LineCounter counter = new LineCounter();   
  305.                 counter.setFileExts(".java"".jsp");   
  306.                 counter.count(folder);   
  307.                 counter.printResult();   
  308.         }   
  309. }   

顺便做了一个壳,调用该类进行计算,对文件的扩展名米有测试,截图如下,选中打开的目录后即开始计算并将结果显示。
根据项目文件的数量、代码行数的多少,效率会有差别。。

UI代码:

Code:
  1. import java.awt.Component;   
  2. import java.awt.Dimension;   
  3. import java.awt.FlowLayout;   
  4. import java.awt.GridLayout;   
  5. import java.awt.Toolkit;   
  6. import java.awt.event.ActionEvent;   
  7. import java.awt.event.ActionListener;   
  8. import java.io.File;   
  9.     
  10. import javax.swing.JButton;   
  11. import javax.swing.JFileChooser;   
  12. import javax.swing.JFrame;   
  13. import javax.swing.JLabel;   
  14. import javax.swing.JPanel;   
  15. import javax.swing.JTextField;   
  16.     
  17. public class LineCounterUI extends JFrame {   
  18.     
  19.         /**  
  20.          *   
  21.          */  
  22.         private static final long serialVersionUID = 1L;   
  23.           
  24.         private JTextField tfTotalLines = new JTextField("0");   
  25.         private JTextField tfCodeLines = new JTextField("0");   
  26.         private JTextField tfCommentLines = new JTextField("0");   
  27.         private JTextField tfCodeWithCommentLines = new JTextField("0");   
  28.         private JTextField tfBlankLines = new JTextField("0");   
  29.         private JTextField tfNonBlankLines = new JTextField("0");   
  30.           
  31.         private JTextField tfExts = new JTextField(".java, .jsp, .js"16);   
  32.     
  33.         public LineCounterUI() {   
  34.                 this.configures();   
  35.                 this.fillComponents();   
  36.                 this.setVisible(true);   
  37.         }   
  38.     
  39.         private void configures() {   
  40.                 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
  41.                 this.setTitle("统计行数用");   
  42.                 this.setSize(450180);   
  43.                 this.setLocation((int) (Toolkit.getDefaultToolkit().getScreenSize()   
  44.                                 .getWidth() - this.getWidth()) / 2, (int) (Toolkit   
  45.                                 .getDefaultToolkit().getScreenSize().getHeight() - this  
  46.                                 .getHeight()) / 2);   
  47.         }   
  48.     
  49.         private void fillComponents() {   
  50.                 this.setLayout(new FlowLayout());   
  51.                   
  52.                 this.add(new JPanel() {   
  53.                         /**  
  54.                          *   
  55.                          */  
  56.                         private static final long serialVersionUID = 1L;   
  57.     
  58.                         {   
  59.                                 this.setPreferredSize(new Dimension(400100));   
  60.                                 this.setLayout(new GridLayout(46));   
  61.                                 this.add(new JLabel("Total Lines", JLabel.CENTER));   
  62.                                 this.add(new JLabel("Blank Lines", JLabel.CENTER));   
  63.                                 this.add(new JLabel("Non-Blank Lines", JLabel.CENTER));   
  64.                                 this.add(tfTotalLines);   
  65.                                 this.add(tfBlankLines);   
  66.                                 this.add(tfNonBlankLines);   
  67.                                 this.add(new JLabel("Only Codes", JLabel.CENTER));   
  68.                                 this.add(new JLabel("Only Comments", JLabel.CENTER));   
  69.                                 this.add(new JLabel("CodeWithComments", JLabel.CENTER));   
  70.                                 this.add(tfCodeLines);   
  71.                                 this.add(tfCommentLines);   
  72.                                 this.add(tfCodeWithCommentLines);   
  73.                                   
  74.                                 tfTotalLines.setEditable(false);   
  75.                                 tfBlankLines.setEditable(false);   
  76.                                 tfNonBlankLines.setEditable(false);   
  77.                                 tfCodeLines.setEditable(false);   
  78.                                 tfCommentLines.setEditable(false);   
  79.                                 tfCodeWithCommentLines.setEditable(false);   
  80.                                   
  81.                                 tfTotalLines.setHorizontalAlignment(JTextField.CENTER);   
  82.                                 tfBlankLines.setHorizontalAlignment(JTextField.CENTER);   
  83.                                 tfNonBlankLines.setHorizontalAlignment(JTextField.CENTER);   
  84.                                 tfCodeLines.setHorizontalAlignment(JTextField.CENTER);   
  85.                                 tfCommentLines.setHorizontalAlignment(JTextField.CENTER);   
  86.                                 tfCodeWithCommentLines.setHorizontalAlignment(JTextField.CENTER);   
  87.                         }   
  88.                 });   
  89.     
  90.                 this.add(new JLabel("要统计的扩展名:"));   
  91.                 this.add(tfExts);   
  92.                   
  93.                 JButton btn = new JButton("打开目录");   
  94.                 this.add(btn);   
  95.                 btn.addActionListener(new ActionListener() {   
  96.     
  97.                         @Override  
  98.                         public void actionPerformed(ActionEvent e) {   
  99.                                 JFileChooser fileChooser = new JFileChooser();   
  100.                                 fileChooser.setApproveButtonText("统计");   
  101.                                 fileChooser.setDialogTitle("选择要统计行数的目录");   
  102.                                 fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);   
  103.                                 int choose = fileChooser.showOpenDialog(((Component)e.getSource()).getParent());   
  104.                                 if (choose == JFileChooser.APPROVE_OPTION){   
  105.                                         File file = fileChooser.getSelectedFile();   
  106.                                         LineCounter counter = new LineCounter();   
  107.                                         counter.setFileExts(tfExts.getText().split(", "));   
  108.                                         counter.count(file.getAbsolutePath());   
  109.                                           
  110.                                         tfTotalLines.setText(String.valueOf(counter.getTotalLines()));   
  111.                                         tfBlankLines.setText(String.valueOf(counter.getBlankLines()));   
  112.                                         tfNonBlankLines.setText(String.valueOf(counter.getNonBlankLines()));   
  113.                                         tfCodeLines.setText(String.valueOf(counter.getCodeLines()));   
  114.                                         tfCommentLines.setText(String.valueOf(counter.getCommentLines()));   
  115.                                         tfCodeWithCommentLines.setText(String.valueOf(counter.getCodeWithCommentsLines()));   
  116.                                 }   
  117.                         }   
  118.                           
  119.                 });   
  120.         }   
  121.     
  122.         /**  
  123.          * @param args  
  124.          */  
  125.         public static void main(String[] args) {   
  126.                 new LineCounterUI();   
  127.         }   
  128.     
  129. }  

 

原创粉丝点击