部分代码如下
// 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
...
// 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
...
line = line.trim();
return !line.equals("") && !line.startsWith("//");
}javadoc 和块注释就比较麻烦了。
// $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) {
}
}
} }}
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:}
char c = '"'; 或者'\"'判断成字符串的开始。可能导致
char c = '"'; /* 注释1
* 注释2
* 注释3
*/
这样的代码,统统变成代码行