部分代码如下
// Count the number of lines with the string of interest.
    int num_lines = 0;
    try {
      // Create a FileReader and then wrap it with BufferedReader.
      FileReader file_reader = new FileReader (file);
      BufferedReader buf_reader = new BufferedReader (file_reader);
 
      // Read each line of the file and look for the string of interest.
      do {
         String line = buf_reader.readLine ();
         if (line == null) break;
          num_lines++;
      } while (true);
      buf_reader.close ();
    }
    catch (IOException e) {
        System.out.println ("IO exception =" + e );
    }
    System.out.printf ("Number of lines   = %d ",num_lines);
  } // main
...

解决方案 »

  1.   

    private boolean lineAvailable(String line) {
      line = line.trim();
      return !line.equals("") && !line.startsWith("//");
    }javadoc 和块注释就比较麻烦了。
      

  2.   

    // ----------------------------------------------------------
    // $Id: $
    // ----------------------------------------------------------
    package test;import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;/**
     * @author Michael J Chane
     * @version $Revision: $ $Date: $
     */
    public class Test {  /**
       * @param args
       * @throws Exception
       */
      public static void main(String[] args) throws Exception {    BufferedReader in = null;
        try {
          // 输入流(就是这段代码,我的文件UTF8的)
          in = new BufferedReader(new InputStreamReader(new FileInputStream(
              "D:/MyProjects/test/test/Test.java"), "UTF8"));      // 当前行是否在块注释内
          boolean blockComment = false;
          // 当前行
          String line = null; /*
                               * 测试用 测试用 测试用
                               */      List<String[]> codeLines = new ArrayList<String[]>(); // 代码行
          List<String[]> commentLines = new ArrayList<String[]>();// 注释行      /* 测试用 */
          int lineNo = 0; // 行号
          while ((line = in.readLine()) != null) { // 这里有个问题,读不出EOF之前的那个"文件末自动换行"
            /* 测试用 */lineNo++; /* 测试用 */
            // 行信息
            String[] lineInfo = new String[] {
                String.valueOf(lineNo), line
            };        // 去除前后White space
            String trim = line.trim();        if (trim.length() == 0) {
              // 纯粹的空白行
              commentLines.add(lineInfo);
              /* 测试用 */continue; // /* 测试用 */
            }        if (!blockComment && trim.startsWith("//")) {
              // 整行都是行注释
              // 如果当前行已经在块注释内,即使以"//"开头,仍然需要继续判断
              commentLines.add(lineInfo);
              continue;
            }        // 块注释判断。由于一行内可能有多个/* */,所以需要逐字判断        boolean codeLine = false; // 是否代码行
            boolean inString = false; // 是否在字符串内
            /* 按照效率考虑,不应一个个字符遍历,而是直接跳到下一"关键字" */
            for (int i = 0; i < trim.length(); i++) {
              if (trim.startsWith("/*", i) && !blockComment && !inString) {
                // 当前位置为"/*",且不在块注释内或字符串内
                blockComment = true;
                i++; // 跳过后面的"*"
                continue; // 判断后面内容
              }          if (trim.startsWith("*/", i) && blockComment && !inString) {
                // 当前位置为"*/",且在块注释内,字符串外
                blockComment = false;
                i++; // 跳过后面的"/"
                continue;
              }          if (trim.startsWith("//", i) && !blockComment && !inString) {
                // 当前位置为"//",且不在块注释内或字符串内
                break; // 之后都属于行注释,无需再判
              }          if (trim.charAt(i) == '"') {
                // 当前字符时双引号
                if (!inString) {
                  // 之前不在字符串内,这是字符串代码开始
                  inString = true;
                } else if (trim.charAt(i - 1) != '\\'
                    || trim.substring(i - 2, i).equals("\\\\")) {
                  // 之前在字符串内,且这个双引号不是转义
                  inString = false; /* 字符串结束 */
                }
              }          if (!blockComment && !inString
                  && !Character.isWhitespace(trim.charAt(i))) {
                // 当前内容不在块注释之内,且非空白,属于代码。但是,还不能break;
                codeLine = true;
                /* 这行 *//* 不是代码行 */
              }
            }        if (codeLine) {
              // 代码行
              codeLines.add(lineInfo);
            } else {
              // 注释行
              commentLines.add(lineInfo);
            }
          }      System.out.printf("总行数:%5d\t代码行数:%5d\t注释或空白行:%5d\n", codeLines.size()
              + commentLines.size(), codeLines.size(), commentLines.size());
          for (String[] lineInfo : codeLines) {
            System.out.printf("%5s:%s\n", lineInfo);
          }    } finally {
          if (in != null) {
            try {
              in.close();
            } catch (Exception ex) {
            }
          }
        }  }}
      

  3.   

    总行数:  136 代码行数:   81 注释或空白行:   55
        4:package test;
        6:import java.io.BufferedReader;
        7:import java.io.FileInputStream;
        8:import java.io.InputStreamReader;
        9:import java.util.ArrayList;
       10:import java.util.List;
       16:public class Test {
       22:  public static void main(String[] args) throws Exception {
       24:    BufferedReader in = null;
       25:    try {
       27:      in = new BufferedReader(new InputStreamReader(new FileInputStream(
       28:          "D:/MyProjects/test/test/Test.java"), "UTF8"));
       31:      boolean blockComment = false;
       33:      String line = null; /*
       37:      List<String[]> codeLines = new ArrayList<String[]>(); // 代码行
       38:      List<String[]> commentLines = new ArrayList<String[]>();// 注释行
       41:      int lineNo = 0; // 行号
       42:      while ((line = in.readLine()) != null) {
       43:        /* 测试用 */lineNo++; /* 测试用 */
       45:        String[] lineInfo = new String[] {
       46:            String.valueOf(lineNo), line
       47:        };
       50:        String trim = line.trim();
       52:        if (trim.length() == 0) {
       54:          commentLines.add(lineInfo);
       55:          /* 测试用 */continue; // /* 测试用 */
       56:        }
       58:        if (!blockComment && trim.startsWith("//")) {
       61:          commentLines.add(lineInfo);
       62:          continue;
       63:        }
       67:        boolean codeLine = false; // 是否代码行
       68:        boolean inString = false; // 是否在字符串内
       70:        for (int i = 0; i < trim.length(); i++) {
       71:          if (trim.startsWith("/*", i) && !blockComment && !inString) {
       73:            blockComment = true;
       74:            i++; // 跳过后面的"*"
       75:            continue; // 判断后面内容
       76:          }
       78:          if (trim.startsWith("*/", i) && blockComment && !inString) {
       80:            blockComment = false;
       81:            i++; // 跳过后面的"/"
       82:            continue;
       83:          }
       85:          if (trim.startsWith("//", i) && !blockComment && !inString) {
       87:            break; // 之后都属于行注释,无需再判
       88:          }
       90:          if (trim.charAt(i) == '"') {
       92:            if (!inString) {
       94:              inString = true;
       95:            } else if (trim.charAt(i - 1) != '\\'
       96:                || trim.substring(i - 2, i).equals("\\\\")) {
       98:              inString = false; /* 字符串结束 */
       99:            }
      100:          }
      102:          if (!blockComment && !inString
      103:              && !Character.isWhitespace(trim.charAt(i))) {
      105:            codeLine = true;
      107:          }
      108:        }
      110:        if (codeLine) {
      112:          codeLines.add(lineInfo);
      113:        } else {
      115:          commentLines.add(lineInfo);
      116:        }
      117:      }
      119:      System.out.printf("总行数:%5d\t代码行数:%5d\t注释或空白行:%5d\n", codeLines.size()
      120:          + commentLines.size(), codeLines.size(), commentLines.size());
      121:      for (String[] lineInfo : codeLines) {
      122:        System.out.printf("%5s:%s\n", lineInfo);
      123:      }
      125:    } finally {
      126:      if (in != null) {
      127:        try {
      128:          in.close();
      129:        } catch (Exception ex) {
      130:        }
      131:      }
      132:    }
      134:  }
      136:}
      

  4.   

    其实还是有小问题的的,比如字符串判断,会把代码
    char c = '"'; 或者'\"'判断成字符串的开始。可能导致
    char c = '"'; /* 注释1
    * 注释2
    * 注释3
    */
    这样的代码,统统变成代码行