天天看点

使用StreamTokenizer统计文件的字符数

 关键技术:

类java.io.streamtokenizer可以获取输入流并将其分析为token(标记)。streamtokenizer的nexttoken方法将读取下一个标记

默认情况下,streamtokenizer认为下列内容是token:字母、数字、除c和c++注释符号以外的其他符号。如符号“/”不是token,注释后的内容也不是,而“\”是token。单引号和双引号以及其中的内容,只能算是一个token。

要统计文件的字符数,不能简单地统计token数,因为字符数不等于token,按照token的规定,引号中的内容就算是10页也算是一个token。如果希望引号和引号中的内容都算作token,应该通过streamtokenizer的ordinarycha方法将单引号和双引号当做普通字符处理。

<!--

code highlighting produced by actipro codehighlighter (freeware)

http://www.codehighlighter.com/

-->package book.io;

import java.io.bufferedreader;

import java.io.filereader;

import java.io.ioexception;

import java.io.streamtokenizer;

/**

 * 使用streamtokenizer来统计文件中的字符数

 * streamtokenizer 类获取输入流并将其分析为“标记”,允许一次读取一个标记。

 * 分析过程由一个表和许多可以设置为各种状态的标志控制。

 * 该流的标记生成器可以识别标识符、数字、引用的字符串和各种注释样式。

 * 

 *  默认情况下,streamtokenizer认为下列内容是token: 字母、数字、除c和c++注释符号以外的其他符号。

 *  如符号"/"不是token,注释后的内容也不是,而"\"是token。单引号和双引号以及其中的内容,只能算是一个token。

 *  统计文章字符数的程序,不是简单的统计token数就万事大吉,因为字符数不等于token。按照token的规定,

 *  引号中的内容就算是10页也算一个token。如果希望引号和引号中的内容都算作token,应该调用下面的代码:

 *     st.ordinarychar('\'');

 * st.ordinarychar('\"');

 */

public class statisfilechars {

    /**

     * 统计字符数

     * @param filename 文件名

     * @return    字符数

     */

    public static long statis(string filename) {

        filereader filereader = null;

        try {

            filereader = new filereader(filename);

            //创建分析给定字符流的标记生成器

            streamtokenizer st = new streamtokenizer(new bufferedreader(

                    filereader));

            //ordinarychar方法指定字符参数在此标记生成器中是“普通”字符。

            //下面指定单引号、双引号和注释符号是普通字符

            st.ordinarychar('\'');

            st.ordinarychar('\"');

            st.ordinarychar('/');

            string s;

            int numbersum = 0;

            int wordsum = 0;

            int symbolsum = 0;

            int total = 0;

            //nexttoken方法读取下一个token.

            //tt_eof指示已读到流末尾的常量。

            while (st.nexttoken() != streamtokenizer.tt_eof) {

                //在调用 nexttoken 方法之后,ttype字段将包含刚读取的标记的类型

                switch (st.ttype) {

                //tt_eol指示已读到行末尾的常量。

                case streamtokenizer.tt_eol:

                    break;

                //tt_number指示已读到一个数字标记的常量

                case streamtokenizer.tt_number:

                    //如果当前标记是一个数字,nval字段将包含该数字的值

                    s = string.valueof((st.nval));

                    system.out.println(s);

                    numbersum += s.length();

                //tt_word指示已读到一个文字标记的常量

                case streamtokenizer.tt_word:

                    //如果当前标记是一个文字标记,sval字段包含一个给出该文字标记的字符的字符串

                    s = st.sval;

                    wordsum += s.length();

                default:

                    //如果以上3中类型都不是,则为英文的标点符号

                    s = string.valueof((char) st.ttype);

                    symbolsum += s.length();

                }

            }

            system.out.println("sum of number = " + numbersum);

            system.out.println("sum of word = " + wordsum);

            system.out.println("sum of symbol = " + symbolsum);

            total = symbolsum + numbersum + wordsum;

            system.out.println("total = " + total);

            return total;

        } catch (exception e) {

            e.printstacktrace();

            return -1;

        } finally {

            if (filereader != null) {

                try {

                    filereader.close();

                } catch (ioexception e1) {

        }

    }

    public static void main(string[] args) {

        string filename = "c:/temp/newtemp.txt";

        statisfilechars.statis(filename);

}

运行结果:

sum of number = 11

sum of word = 55

sum of symbol = 4

total = 70

继续阅读