關鍵技術:
- 類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();
break;
//TT_WORD指示已讀到一個文字標記的常量
case StreamTokenizer.TT_WORD:
//如果當前標記是一個文字標記,sval字段包含一個給出該文字標記的字符的字符串
s = st.sval;
wordSum += s.length();
break;
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