源码研究小工具--删除代码注释

dxcai 2005-07-13 09:37:02
一个去除java源码注释的小工具

我们在研究java API的源码时,有时会觉得注释太多了(大部分代码都是浅显易懂的),往往比代码本身

还多(sun做得真够体贴入微的),以至我们不得不在大块大块的注释中寻找代码。
于是我们就会想:要是有一个无注释的版本就好了,一个class的代码都可以一览无余,省却许多注释来障

目。当确实看不懂时才看注释版本。
这就是小弟花点时间做这个class的意义。下边把代码贴出来,以方便大家。
运行时要指定两个参数:输入目录和输出目录(单个文件也可以)


/*
*把指定目录下的java源码去掉注释放到另一目录下
*作者:钝秀才 2005/7/13
*/

import java.io.*;

public class Dc {

static String srcStr = "E:\\j2seAPIsrc";
static String desStr = "E:\\j2seAPIsrc_无注释";

//处理文件
private void profile(File src, File des) throws Exception {

StringBuffer content = new StringBuffer();
String temp;
int start;
int end;
int from = 0;

BufferedReader br = new BufferedReader(new FileReader(src));
BufferedWriter bw = new BufferedWriter(new FileWriter(des));

while ( (temp = br.readLine()) != null) {
content.append(temp);
content.append("\n");
}

while ( (start = content.indexOf("/*", from)) != -1) {
end = content.indexOf("*/", start) + 2;
content.delete(start, end);
from = start;
}

from = 0;
int e;
//指定from以提高速度
while ( (start = content.indexOf("//", from)) != -1) {
e = content.indexOf("\n", start);
end = (e == -1) ? content.length() : (e + 1);
content.delete(start, end);
from = start;
}

bw.write(content.toString());
br.close();
bw.close();
}


//处理目录
private void prodir(File src, File des) throws Exception {

des.mkdir(); //创建目录
File[] files = src.listFiles();

for (int i = 0; i < files.length; i++) {
//下一级目录/文件
File nf = new File(des, files[i].getName());
if (files[i].isDirectory()) {
//是目录,递归
prodir(files[i], nf);
}
else { //文件
profile(files[i], nf);
}
}
}


//输入目录还是文件
public void dispReq(File src, File des) throws Exception {

if (src.isDirectory()) {
prodir(src, des);
}
else {
profile(src, des);
}
}


public static void main(String[] args) {

if (args.length >= 2) {
srcStr = args[0];
desStr = args[1];
}
File src = new File(srcStr);
File des = new File(desStr);
try {
new Dc().dispReq(src, des);
}
catch (Exception ex) {
System.out.println(ex);
}
}

}





...全文
531 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zez 2005-07-14
  • 打赏
  • 举报
回复
看你的代码量就知道bug肯定不少...
呵呵...
对于
//*
/* xxxxx "*/"
/*//
"// xxx"
/* // */
// /*xxx */


等问题你的有处理没?:)
dlxu 2005-07-14
  • 打赏
  • 举报
回复
人家有注释你还不开心啊,那你可以用IDE自带的那种块拉伸工具把注释给拉掉
dxcai 2005-07-14
  • 打赏
  • 举报
回复
高效版本!!!
基于上面的考虑,我对代码做了一些修改,以提高效率。主要修改了profile方法。
测试结果发现,前一版本处理整个j2se 的API需要124094毫秒,而新版本只需要23031毫秒,快了5倍多!真让人兴奋!



/*
*把指定目录下的java源码去掉注释放到另一目录下
*作者:钝秀才 2005/7/14
*/

import java.io.*;

//把指定目录下的java源码去掉注释放到另一目录下
public class Dc2 {

static String srcStr = "E:\\j2seAPIsrc";
static String desStr = "E:\\j2seAPIsrc_版本2";

//处理文件
private void profile(File src, File des) throws Exception {

StringBuffer content = new StringBuffer();
StringBuffer output1 = new StringBuffer();
StringBuffer output2 = new StringBuffer();
String temp;
int start = 0;
int end = 0;
int from = 0;

BufferedReader br = new BufferedReader(new FileReader(src));
BufferedWriter bw = new BufferedWriter(new FileWriter(des));

while ( (temp = br.readLine()) != null) {
content.append(temp);
content.append("\n");
}

//弃掉/* ... */注释,未考虑以//*开头的注释,
//且未考虑/*、*/等包含在""内的情形
//指定from以提高速度
while ( (start = content.indexOf("/*", start)) != -1) {
output1.append(content.substring(from, start));
from = content.indexOf("*/", start) + 2;
start = from;
}
output1.append(content.substring(from));

//弃掉// ... 注释
start = 0;
from = 0;
while ( (start = output1.indexOf("//", start)) != -1) {
output2.append(output1.substring(from, start));
from = output1.indexOf("\n", start); //保留回车换行
if (from == -1) { //不以"\n"结束
from = output1.length();
break;
}
start = from;
}
output2.append(output1.substring(from));

bw.write(output2.toString());
br.close();
bw.close();
}


//处理目录
private void prodir(File src, File des) throws Exception {

des.mkdir(); //创建目录
File[] files = src.listFiles();

for (int i = 0; i < files.length; i++) {
//下一级目录/文件
File nf = new File(des, files[i].getName());
if (files[i].isDirectory()) {
//是目录,递归
prodir(files[i], nf);
}
else { //文件
profile(files[i], nf);
}
}
}


//输入目录还是文件
public void dispReq(File src, File des) throws Exception {

if (src.isDirectory()) {
prodir(src, des);
}
else {
profile(src, des);
}
}


public static void main(String[] args) {

long starttime = System.currentTimeMillis();

if (args.length >= 2) {
srcStr = args[0];
desStr = args[1];
}
File src = new File(srcStr);
File des = new File(desStr);
try {
new Dc2().dispReq(src, des);
}
catch (Exception ex) {
System.out.println(ex);
}
long endtime = System.currentTimeMillis();
long usetime = endtime - starttime;
System.out.println("total use: " + usetime + " ms.");
}

}




dxcai 2005-07-14
  • 打赏
  • 举报
回复
谢谢!
这里是先处理/* .... */ 再处理 //....的,确实存在一些隐含问题,
严格一点应该找出/* 与 // 谁先出现。
另外,如果""里面包含/*、*/、//也会有问题。这个我不打算处理了

我又想到了一点,在profile方法中,不断的在一个StringBuffer中delete可能效率不高,因为每delete一次就要重新arraycopy整个StringBuffer的内容。解决办法是多用一个StringBuffer
dxcai 2005-07-14
  • 打赏
  • 举报
回复
TO:dlxu(Coding超过了10W行)
生成无注释版本的考虑是:
1.希望在一屏内就可以看清楚一个class的所有method。
2.java src 的大部分注释都是method功能描述,而基本上一看方法名就可以知道其功能。
3./**...*/注释是为了生成doc的,其中包含大量的html标签、@..标签等,看起来比较杂乱。不如查看对应javadoc更方便。
4.为了锻炼理解力。

eclipse的注释需要一个一个的收起来。我查阅源码基本都是用写字板的,多轻便,不必要随时启动一个ide.

23,404

社区成员

发帖
与我相关
我的任务
社区描述
Java 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧