用Java分析C源代码中头文件使用频率

来源:互联网 发布:自考和网络教育认可度 编辑:程序博客网 时间:2024/04/30 01:32

想法:

分析LinuxC运行库各个头文件的使用频率,可以大致判断哪些C库头文件是常用的、基础的或重要的,给Linux系统编程学习者提供一个方向。其实最精细的统计分析应该是针对Linux系统调用和C标准库函数,这样对LinuxC初学者更有指导意义,不过现在还不知道怎么实现。最终选择BusyBox作为研究对象,它主要依赖Linux C运行库实现各种Linux命令和工具。

 

BusyBox是一个集成了一百多个最常用linux命令和工具的软件。BusyBox包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例grep、find、mount以及telnet。有些人将BusyBox 称为 Linux 工具里的瑞士军刀。简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也包含了Android 系统的自带的shell。

 

搜索Busybox源代码文件,提取出含有include语句的代码行

find -name '*.c' -o-name '*.h' | xargs grep include > busybox-stats.txt

 

./console-tools/setlogcons.c:#include"libbb.h"

./console-tools/clear.c:#include"libbb.h"

./console-tools/openvt.c:#include<linux/vt.h>

./console-tools/openvt.c:#include"libbb.h"

./console-tools/setkeycodes.c:#include"libbb.h"

./console-tools/fgconsole.c:#include"libbb.h"

./console-tools/resize.c:#include"libbb.h"

./console-tools/showkey.c:#include"libbb.h"

./console-tools/showkey.c:#include<linux/kd.h>

./console-tools/loadfont.c:#include"libbb.h"

./console-tools/loadfont.c:#include<sys/kd.h>

./console-tools/setconsole.c:#include"libbb.h"

...

 

在NotePad++下对文本进行过滤,排序,最终得到如下数据

 

arpa/inet.h

arpa/inet.h

arpa/inet.h

arpa/inet.h

arpa/inet.h

arpa/inet.h

arpa/inet.h

arpa/telnet.h

arpa/telnet.h

asm/types.h

asm/types.h

asm/types.h

asm/unistd.h

...

 

 

这些头文件就是Linux C运行库的头文件。

 

现在我们要做的就是用Java编写一个程序,统计每个头文件在文本文件中出现的次数并排序。

比如"arpa/inet.h"这个头文件出现的次数为7.

 

工程目录结构:

 E:\workspace\JavaApp\WordStats 的目录

 

2014-04-22  15:03   <DIR>          .

2014-04-22  15:03   <DIR>          ..

2014-04-18  12:16            10,797 busybox-stats.txt

2014-04-22  14:58             2,229 WordStats.java

 

WordStats.java

 

import java.io.BufferedReader;import java.io.FileReader;import java.io.File;import java.io.FileWriter;import java.io.PrintWriter;import java.io.IOException;import java.util.*;import java.util.Map.Entry;import java.text.DecimalFormat;public class WordStats {    public static void main(String[] args) throws IOException {        //System.out.println("Hello World!");        //System.out.println(args.length);        // 解析参数        int argc = args.length;        String inputFilename;        String outputFilename;        if (argc == 2) {            inputFilename = args[0];            outputFilename = args[1];            //System.out.println(args[0]);            //System.out.println(args[1]);         } else {            System.out.println("usage: java WordStats <inputfile> <outputfile>");            return;         }                // 打开输入和输出文件        BufferedReader in = new BufferedReader(new FileReader(inputFilename));        File fout = new File(outputFilename);        PrintWriter out = new PrintWriter(new FileWriter(fout));                // 使用HashMap来保存统计数据        Map<String, Integer> stats = new HashMap<String, Integer>();        String str;        Integer count;        // 解析输入文本并统计        while ((str = in.readLine()) != null) {            //System.out.println(str);            if (stats.containsKey(str)) {                count = (Integer)stats.get(str);                count++;                stats.put(str, count);            } else {                count = 1;                stats.put(str, count);            }        }                // 使用ArrayList来对Value进行排序        ArrayList<Entry<String,Integer>> l = new ArrayList<Entry<String,Integer>>(stats.entrySet());        Collections.sort(l, new Comparator<Map.Entry<String, Integer>>() {            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {                return (o2.getValue() - o1.getValue());            }        });                // 将统计结果保存到输出文件        for (Entry<String, Integer> e : l) {            //System.out.println(new DecimalFormat("000").format(e.getValue()) + " " + e.getKey());            out.println(new DecimalFormat("000").format(e.getValue()) + " " + e.getKey());        }                // 关闭输入和输出文件        in.close();        out.close();    }}

 

 

用法:

usage: java WordStats<inputfile> <outputfile>

 

编译运行:

E:\workspace\JavaApp\WordStats>javac WordStats.java

 

E:\workspace\JavaApp\WordStats>java WordStats busybox-stats.txt output.txt

 

运行结果:

Output.txt

 

117stdio.h

113string.h

092unistd.h

061sys/types.h

055stdlib.h

050sys/stat.h

048time.h

046fcntl.h

039errno.h

025syslog.h

021sys/utsname.h

020ctype.h

019net/if.h

012sys/ioctl.h

012sys/mount.h

011mntent.h

011fnmatch.h

010netinet/in.h

010dirent.h

008linux/types.h

...

 

从中可以分析出,排在前面的那些头文件都是我们在做Linux C应用程序开发中常用的头文件。其中stdio.hstring.h、和stdlib.h都是C标准库头文件。在学习Linux C开发的过程中,可以重点抓这些靠前的头文件。


Github:

https://github.com/maxliaops/WordStats


2 0