环境:eclipsse, jdk1.6, 没有使用第三方的包,都是JDK有的。

注意,项目源文件我都使用的是UTF-8的编码格式,如果不是,代码里面的汉字注释会显示乱码。

设置UTF-8:windows->Preferences->General->Workspace 页面上Text file encoding,选择Other UTF-8

项目结构:

1.字典文件

dic.txt 下载地址:http://download.csdn.net/detail/wssiqi/5056993

这里只摘录一部分内容,里面共收录了20902个汉字

[plain] view plaincopy
  1. 19968,一,一,1,1,GGLL,A,yi1,yī
  2. 19969,丁,一,2,12,SGH,AI,ding1,dīng,zheng1,zhēng
  3. 19970,丂,一,2,15,GNV,AZVV,kao3,kǎo,qiao3,qiǎo,yu2,yú
  4. 19971,七,一,2,15,AGN,HD,qi1,qī
  5. 19972,丄,一,2,21,HGD,IAVV,shang4,shàng
  6. 19973,丅,一,2,12,GHK,AIAA,xia4,xià
  7. 19974,丆,一,2,13,DGT,GDAA,han3,hǎn
  8. 19975,万,一,3,153,DNV,,wan4,wàn,mo4,mò
  9. 19976,丈,一,3,134,DYI,AOS,zhang4,zhàng
  10. 19977,三,一,3,111,DGGG,CD,san1,sān
  11. 19978,上,一,3,211,HHGG,IDA,shang3,shǎng,shang4,shàng
  12. 19979,下,一,3,124,GHI,AID,xia4,xià
  13. 19980,丌,一,3,132,GJK,AND,ji1,jī,qi2,qí
  14. 19981,不,一,4,1324,GII,GI,fou3,fǒu,bu4,bù
  15. 19982,与,一,3,151,GNGD,AZA,yu4,yù,yu3,yǔ,yu2,yú
  16. 19983,丏,一,4,1255,GHNN,AIZY,mian3,miǎn
  17. 19984,丐,一,4,1215,GHNV,AIZ,gai4,gài
  18. 19985,丑,一,4,5211,NFD,XED,chou3,chǒu
  19. 19986,丒,一,4,5341,VYGF,YDSA,chou3,chǒu

2.Dic.java

[java] view plaincopy
  1. package com.siqi.dict;
  2. import java.io.BufferedReader;
  3. import java.io.ByteArrayInputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.InputStreamReader;
  7. import java.nio.charset.Charset;
  8. /**
  9. * 汉字本地字典。 <br/>
  10. * 本地字典数据来自于<a href=http://www.zdic.net/search/?c=2>汉典</a>
  11. * 实现了一下常用的需求,例如返回拼音,五笔,拼音首字母,笔画数目,笔画顺序。
  12. *
  13. * @author siqi
  14. *
  15. */
  16. public class Dic {
  17. /**
  18. * 设置是否输出调试信息
  19. */
  20. private static boolean DEBUG = true;
  21. /**
  22. * 默认编码
  23. */
  24. public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
  25. /**
  26. * 汉字Unicode最小编码
  27. */
  28. public static final int CN_U16_CODE_MIN = 0x4e00;
  29. /**
  30. * 汉字Unicode最大编码
  31. */
  32. public static final int CN_U16_CODE_MAX = 0x9fa5;
  33. /**
  34. * 本地字典文件名
  35. */
  36. public static final String DIC_FILENAME = "dic.txt";
  37. /**
  38. * 字典数据
  39. */
  40. public static byte[] bytes = new byte[0];
  41. /**
  42. * 字典汉字数目
  43. */
  44. public static int count = 0;
  45. /**
  46. * 汉字unicode值在一条汉字信息的位置<br/>
  47. * 汉字信息,例:"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá"
  48. */
  49. public static int INDEX_UNICODE = 0;
  50. /**
  51. * 汉字在一条汉字信息的位置<br/>
  52. * 汉字信息,例:"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá"
  53. */
  54. public static int INDEX_CHARACTER = 1;
  55. /**
  56. * 汉字部首在一条汉字信息的位置<br/>
  57. * 汉字信息,例:"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá"
  58. */
  59. public static int INDEX_BUSHOU = 2;
  60. /**
  61. * 汉字笔画在一条汉字信息的位置<br/>
  62. * 汉字信息,例:"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá"
  63. */
  64. public static int INDEX_BIHUA = 3;
  65. /**
  66. * 汉字笔画顺序在一条汉字信息的位置<br/>
  67. * 汉字信息,例:"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá"
  68. */
  69. public static int INDEX_BISHUN = 4;
  70. /**
  71. * 汉字五笔在一条汉字信息的位置<br/>
  72. * 汉字信息,例:"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá"
  73. */
  74. public static int INDEX_WUBI = 5;
  75. /**
  76. * 汉字郑码在一条汉字信息的位置<br/>
  77. * 汉字信息,例:"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá"
  78. */
  79. public static int INDEX_ZHENGMA = 6;
  80. /**
  81. * 第一个汉字拼音(英文字母)在一条汉字信息的位置<br/>
  82. * 汉字信息,例:"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá"
  83. */
  84. public static int INDEX_PINYIN_EN = 7;
  85. /**
  86. * 第一个汉字拼音(中文字母)在一条汉字信息的位置<br/>
  87. * 汉字信息,例:"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá"
  88. */
  89. public static int INDEX_PINYIN_CN = 8;
  90. /**
  91. * 装载字典
  92. */
  93. static {
  94. long time = System.currentTimeMillis();
  95. try {
  96. LoadDictionary();
  97. count = count();
  98. if (DEBUG) {
  99. System.out.println("成功载入字典" + new File(DIC_FILENAME).getCanonicalPath() + " ,用时:"
  100. + (System.currentTimeMillis() - time) + "毫秒,载入字符数"+count);
  101. }
  102. } catch (Exception e) {
  103. try {
  104. System.out.println("载入字典失败" + new File(DIC_FILENAME).getCanonicalPath()+"\r\n");
  105. } catch (Exception e1) {
  106. }
  107. e.printStackTrace();
  108. }
  109. }
  110. /**
  111. * 获取汉字unicode值
  112. *
  113. * @param ch
  114. *            汉字
  115. * @return 返回汉字的unicode值
  116. * @throws Exception
  117. */
  118. public static String GetUnicode(Character ch) throws Exception {
  119. return GetCharInfo(ch, INDEX_UNICODE);
  120. }
  121. /**
  122. * 获取拼音(英文字母)
  123. *
  124. * @param ch
  125. *            单个汉字字符
  126. * @return 返回汉字的英文字母拼音。如 "大"->"da4"。
  127. * @throws Exception
  128. */
  129. public static String GetPinyinEn(Character ch) throws Exception {
  130. return GetCharInfo(ch, INDEX_PINYIN_EN);
  131. }
  132. /**
  133. * 返回汉字字符串的拼音(英文字母)
  134. *
  135. * @param str
  136. *            汉字字符串
  137. * @return 返回汉字字符串的拼音。将字符串中的汉字替换成拼音,其他字符不变。拼音中间会有空格。 注意,对于多音字,返回的拼音可能不正确。
  138. * @throws Exception
  139. */
  140. public static String GetPinyinEn(String str) throws Exception {
  141. StringBuffer sb = new StringBuffer();
  142. for (int i = 0; i < str.length(); i++) {
  143. char ch = str.charAt(i);
  144. if (isChineseChar(ch)) {
  145. sb.append(GetPinyinEn(ch) + " ");
  146. } else {
  147. sb.append(ch);
  148. }
  149. }
  150. return sb.toString().trim();
  151. }
  152. /**
  153. * 获取拼音(中文字母)
  154. *
  155. * @param ch
  156. *            单个汉字字符
  157. * @return 返回汉字的中文字母拼音。如 "打"->"dǎ"。
  158. * @throws Exception
  159. */
  160. public static String GetPinyinCn(Character ch) throws Exception {
  161. return GetCharInfo(ch, INDEX_PINYIN_CN);
  162. }
  163. /**
  164. * 返回汉字字符串的拼音(中文字母)
  165. *
  166. * @param str
  167. *            汉字字符串
  168. * @return 返回汉字字符串的拼音。将字符串中的汉字替换成拼音,其他字符不变。拼音中间会有空格。 注意,对于多音字,返回的拼音可能不正确。
  169. * @throws Exception
  170. */
  171. public static String GetPinyinCn(String str) throws Exception {
  172. StringBuffer sb = new StringBuffer();
  173. for (int i = 0; i < str.length(); i++) {
  174. char ch = str.charAt(i);
  175. if (isChineseChar(ch)) {
  176. sb.append(GetPinyinCn(ch) + " ");
  177. } else {
  178. sb.append(ch);
  179. }
  180. }
  181. return sb.toString().trim();
  182. }
  183. /**
  184. * 返回拼音首字母
  185. *
  186. * @param ch
  187. * @return
  188. * @throws Exception
  189. */
  190. public static String GetFirstLetter(Character ch) throws Exception {
  191. if (isChineseChar(ch)) {
  192. return GetPinyinEn(ch).substring(0, 1);
  193. } else {
  194. return "";
  195. }
  196. }
  197. /**
  198. * 返回汉字字符串拼音首字母,如果不是汉字,会被忽略掉。
  199. *
  200. * @param str
  201. *            汉字字符串
  202. * @return
  203. * @throws Exception
  204. */
  205. public static String GetFirstLetter(String str) throws Exception {
  206. StringBuffer sb = new StringBuffer();
  207. for (int i = 0; i < str.length(); i++) {
  208. char ch = str.charAt(i);
  209. if (isChineseChar(ch)) {
  210. sb.append(GetFirstLetter(ch));
  211. }
  212. }
  213. return sb.toString().trim();
  214. }
  215. /**
  216. * 获取汉字部首
  217. *
  218. * @param ch
  219. *            汉字
  220. * @return 返回汉字的部首
  221. * @throws Exception
  222. */
  223. public static String GetBushou(Character ch) throws Exception {
  224. return GetCharInfo(ch, INDEX_BUSHOU);
  225. }
  226. /**
  227. * 获取汉字笔画数目
  228. *
  229. * @param ch
  230. *            汉字
  231. * @return 返回汉字的笔画数目
  232. * @throws Exception
  233. */
  234. public static String GetBihua(Character ch) throws Exception {
  235. return GetCharInfo(ch, INDEX_BIHUA);
  236. }
  237. /**
  238. * 获取汉字笔画顺序
  239. *
  240. * @param ch
  241. *            汉字
  242. * @return 返回汉字的笔画顺序
  243. * @throws Exception
  244. */
  245. public static String GetBishun(Character ch) throws Exception {
  246. return GetCharInfo(ch, INDEX_BISHUN);
  247. }
  248. /**
  249. * 获取汉字五笔
  250. *
  251. * @param ch
  252. *            汉字
  253. * @return 返回汉字五笔
  254. * @throws Exception
  255. */
  256. public static String GetWubi(Character ch) throws Exception {
  257. return GetCharInfo(ch, INDEX_WUBI);
  258. }
  259. /**
  260. * 获取汉字郑码
  261. *
  262. * @param ch
  263. *            汉字
  264. * @return 返回汉字郑码
  265. * @throws Exception
  266. */
  267. public static String GetZhengma(Character ch) throws Exception {
  268. return GetCharInfo(ch, INDEX_ZHENGMA);
  269. }
  270. /**
  271. * 从字典中获取汉字信息
  272. *
  273. * @param ch
  274. *            要查询的汉字
  275. * @return 返回汉字信息,如"25171,打,扌,5,12112,RSH,DAI,da3,dǎ,da2,dá" <br/>
  276. *         第一是汉字unicode值<br/>
  277. *         第二是汉字<br/>
  278. *         第三是汉字部首<br/>
  279. *         第四是汉字笔画<br/>
  280. *         第五是汉字笔画顺序("12345"分别代表"横竖撇捺折")<br/>
  281. *         第六是汉字五笔<br/>
  282. *         第七是汉字郑码<br/>
  283. *         第八及以后是汉字的拼音(英文字母拼音和中文字母拼音)<br/>
  284. * @throws Exception
  285. */
  286. public static String GetCharInfo(Character ch) throws Exception {
  287. if (!isChineseChar(ch)) {
  288. throw new Exception("'" + ch + "' 不是一个汉字!");
  289. }
  290. String result = "";
  291. ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
  292. BufferedReader br = new BufferedReader(new InputStreamReader(bais));
  293. String strWord;
  294. while ((strWord = br.readLine()) != null) {
  295. if (strWord.startsWith(String.valueOf(ch.hashCode()))) {
  296. result = strWord;
  297. break;
  298. }
  299. }
  300. br.close();
  301. bais.close();
  302. return result;
  303. }
  304. /**
  305. * 返回汉字信息
  306. *
  307. * @param ch
  308. *            汉字
  309. * @param index
  310. *            信息所在的Index
  311. * @return
  312. * @throws Exception
  313. */
  314. private static String GetCharInfo(Character ch, int index) throws Exception {
  315. if (!isChineseChar(ch)) {
  316. throw new Exception("'" + ch + "' 不是一个汉字!");
  317. }
  318. // 获取汉字信息
  319. String charInfo = GetCharInfo(ch);
  320. String result = "";
  321. try {
  322. result = charInfo.split(",")[index];
  323. } catch (Exception e) {
  324. throw new Exception("请查看字典中" + ch + "汉字记录是否正确!");
  325. }
  326. return result;
  327. }
  328. /**
  329. * 载入字典文件到内存。
  330. * @throws Exception
  331. */
  332. private static void LoadDictionary() throws Exception {
  333. File file = new File(DIC_FILENAME);
  334. bytes = new byte[(int) file.length()];
  335. FileInputStream fis = new FileInputStream(file);
  336. fis.read(bytes, 0, bytes.length);
  337. fis.close();
  338. }
  339. /**
  340. * 判断字符是否为汉字,在测试的时候,我发现汉字的字符的hashcode值 跟汉字Unicode
  341. * 16的值一样,所以可以用hashcode来判断是否为汉字。
  342. *
  343. * @param ch
  344. *            汉字
  345. * @return 是汉字返回true,否则返回false。
  346. */
  347. public static boolean isChineseChar(Character ch) {
  348. if (ch.hashCode() >= CN_U16_CODE_MIN
  349. && ch.hashCode() <= CN_U16_CODE_MAX) {
  350. return true;
  351. } else {
  352. return false;
  353. }
  354. }
  355. /**
  356. *
  357. * @return 返回字典包含的汉字数目。
  358. * @throws Exception
  359. */
  360. private static int count() throws Exception {
  361. int cnt = 0;
  362. ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
  363. BufferedReader br = new BufferedReader(new InputStreamReader(bais));
  364. while (br.readLine() != null) {
  365. cnt++;
  366. }
  367. br.close();
  368. bais.close();
  369. return cnt;
  370. }
  371. }

3.Sample.java

如何使用字典

[java] view plaincopy
  1. package com.siqi.dict;
  2. /**
  3. * 包含两个实例,示例如何获取汉字的拼音等信息。
  4. * @author siqi
  5. *
  6. */
  7. public class Sample {
  8. /**
  9. * 字典使用实例
  10. *
  11. * @param args
  12. */
  13. public static void main(String[] args) {
  14. try {
  15. long time = System.currentTimeMillis();
  16. char ch = '打';
  17. //汉字单个字符
  18. System.out.println("====打字信息开始====");
  19. System.out.println("首字母:"+Dic.GetFirstLetter(ch));
  20. System.out.println("拼音(中):"+Dic.GetPinyinCn(ch));
  21. System.out.println("拼音(英):"+Dic.GetPinyinEn(ch));
  22. System.out.println("部首:"+Dic.GetBushou(ch));
  23. System.out.println("笔画数目:"+Dic.GetBihua(ch));
  24. System.out.println("笔画:"+Dic.GetBishun(ch));
  25. System.out.println("五笔:"+Dic.GetWubi(ch));
  26. System.out.println("====打字信息结束====");
  27. //汉字字符串
  28. System.out.println("\r\n====汉字字符串====");
  29. System.out.println(Dic.GetPinyinEn("返回汉字字符串的拼音。"));
  30. System.out.println(Dic.GetPinyinCn("返回汉字字符串的拼音。"));
  31. System.out.println(Dic.GetFirstLetter("返回汉字字符串的拼音。"));
  32. System.out.println("====汉字字符串====\r\n");
  33. System.out.println("用时:"+(System.currentTimeMillis()-time)+"毫秒");
  34. } catch (Exception e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. }

4.结果

[html] view plaincopy
  1. ====打字信息开始====
  2. 成功载入字典C:\workspaces\01_java\DictLocal\dic.txt ,用时:15毫秒,载入字符数20902
  3. 首字母:d
  4. 拼音(中):dǎ
  5. 拼音(英):da3
  6. 部首:扌
  7. 笔画数目:5
  8. 笔画:12112
  9. 五笔:RSH
  10. ====打字信息结束====
  11. ====汉字字符串====
  12. fan3 hui2 han4 zi4 zi4 fu2 chuan4 di2 pin1 yin1 。
  13. fǎn huí hàn zì zì fú chuàn dí pīn yīn 。
  14. fhhzzfcdpy
  15. ====汉字字符串====
  16. Memory(Used/Total) : 1539/15872 KB
  17. 用时:218毫秒

待会再上传如何获取字典文件的,我是通过收集http://www.zdic.net/zd/的网页来获取的

=============补充,如何获取汉字的信息================

=============所有的信息都是从汉典网站上获取的=========

目录结构为:

环境:eclipsse, jdk1.6, 没有使用第三方的包,都是JDK有的。

注意,项目源文件我都使用的是UTF-8的编码格式,如果不是,代码里面的汉字注释会显示乱码。

设置UTF-8:windows->Preferences->General->Workspace 页面上Text file encoding,选择Other UTF-8

包说明:

com.siqi.http

Httpclient.Java是我写的一个简单的获取网页的类,用来获取网页内容;

com.siqi.dict

DictMain.java用来下载汉字网页,从中获取汉字的拼音信息,并保存到data.dat中

DownloadThread.java用来下载网页(多线程)

com.siqi.pinyin

PinYin.java在执行过DictMain.java后,会生成一个data.dat,把这个文件拷贝到com.siqi.pinyin包下面,就可以调用PinYin.java里面的函数得到汉字的拼音了

PinYinEle.java一个汉字->拼音->Unicode的模型

源码:

Httpclient.java 可以用来获取网页,可以的到网页内容,网页编码和网页的header,简版

[java] view plaincopy
  1. package com.siqi.http;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.net.Socket;
  5. import java.net.URLEncoder;
  6. import java.util.regex.Matcher;
  7. import java.util.regex.Pattern;
  8. /**
  9. * 使用SOCKET实现简单的网页GET和POST
  10. *
  11. * @author siqi
  12. *
  13. */
  14. public class Httpclient {
  15. /**
  16. * processUrl 参数 HTTP GET
  17. */
  18. public static final int METHOD_GET = 0;
  19. /**
  20. * processUrl 参数 HTTP POST
  21. */
  22. public static final int METHOD_POST = 1;
  23. /**
  24. * HTTP GET的报头,简化版
  25. */
  26. public static final String HEADER_GET = "GET %s HTTP/1.0\r\nHOST: %s\r\n\r\n";
  27. /**
  28. * HTTP POST的报头,简化版
  29. */
  30. public static final String HEADER_POST = "POST %s HTTP/1.0\r\nHOST: %s\r\nContent-Length: 0\r\n\r\n";
  31. /**
  32. * 网页报头和内容的分割符
  33. */
  34. public static final String CONTENT_SEPARATOR = "\r\n\r\n";
  35. /**
  36. * 网页请求响应内容byte
  37. */
  38. private byte[] bytes = new byte[0];
  39. /**
  40. * 网页报头
  41. */
  42. private String header = "";
  43. /**
  44. * 网页内容
  45. */
  46. private String content = "";
  47. /**
  48. * 网页编码,默认为UTF-8
  49. */
  50. public static final String CHARSET_DEFAULT = "UTF-8";
  51. /**
  52. * 网页编码
  53. */
  54. private String charset = CHARSET_DEFAULT;
  55. /**
  56. * 使用Httpclient的例子
  57. *
  58. * @param args
  59. * @throws Exception
  60. */
  61. public static void main(String[] args) throws Exception {
  62. Httpclient httpclient = new Httpclient();
  63. // 请求百度首页(手机版)
  64. httpclient.processUrl("http://m.baidu.com/");
  65. System.out.println("获取网页http://m.baidu.com/");
  66. System.out.println("报头为:\r\n" + httpclient.getHeader());
  67. System.out.println("内容为:\r\n" + httpclient.getContent());
  68. System.out.println("编码为:\r\n" + httpclient.getCharset());
  69. System.out.println("************************************");
  70. // 使用百度搜索"中国"(手机版)
  71. // 这是手机百度搜索框的源码 <input id="word" type="text" size="20" maxlength="64"
  72. // name="word">
  73. String url = String.format("http://m.baidu.com/s?word=%s",
  74. URLEncoder.encode("中国", CHARSET_DEFAULT));
  75. httpclient.processUrl(url, METHOD_POST);
  76. System.out.println("获取网页http://m.baidu.com/s?word=中国");
  77. System.out.println("报头为:\r\n" + httpclient.getHeader());
  78. System.out.println("内容为:\r\n" + httpclient.getContent());
  79. System.out.println("编码为:\r\n" + httpclient.getCharset());
  80. }
  81. /**
  82. * 初始化,设置所有变量为默认值
  83. */
  84. private void init() {
  85. this.bytes = new byte[0];
  86. this.charset = CHARSET_DEFAULT;
  87. this.header = "";
  88. this.content = "";
  89. }
  90. /**
  91. * 获取网页报头header
  92. *
  93. * @return
  94. */
  95. public String getHeader() {
  96. return header;
  97. }
  98. /**
  99. * 获取网页内容content
  100. *
  101. * @return
  102. */
  103. public String getContent() {
  104. return content;
  105. }
  106. /**
  107. * 获取网页编码
  108. *
  109. * @return
  110. */
  111. public String getCharset() {
  112. return charset;
  113. }
  114. /**
  115. * 请求网页内容(使用HTTP GET)
  116. *
  117. * @param url
  118. * @throws Exception
  119. */
  120. public void processUrl(String url) throws Exception {
  121. processUrl(url, METHOD_GET);
  122. }
  123. /**
  124. * 使用Socket请求(获取)一个网页。<br/>
  125. * 例如:<br/>
  126. * processUrl("http://www.baidu.com/", METHOD_GET)会获取百度首页;<br/>
  127. *
  128. * @param url
  129. *            这个网页或者网页内容的地址
  130. * @param method
  131. *            请求网页的方法: METHOD_GET或者METHOD_POST
  132. * @throws Exception
  133. */
  134. public void processUrl(String url, int method) throws Exception {
  135. init();
  136. // url = "http://www.zdic.net/search/?c=2&q=%E5%A4%A7";
  137. // 规范化链接,当网址为http://www.baidu.com时,将网址变为:http://www.baidu.com/
  138. Matcher mat = Pattern.compile("https?://[^/]+").matcher(url);
  139. if (mat.find() && mat.group().equals(url)) {
  140. url += "/";
  141. }
  142. Socket socket = new Socket(getHostUrl(url), 80); // 设置要连接的服务器地址
  143. socket.setSoTimeout(3000); // 设置超时时间为3秒
  144. String request = null;
  145. // 构造请求,详情请参考HTTP协议(RFC2616)
  146. if (method == METHOD_POST) {
  147. request = String.format(HEADER_POST, getSubUrl(url),
  148. getHostUrl(url));
  149. } else {
  150. request = String
  151. .format(HEADER_GET, getSubUrl(url), getHostUrl(url));
  152. }
  153. socket.getOutputStream().write(request.getBytes());// 发送请求
  154. this.bytes = InputStream2ByteArray(socket.getInputStream());// 读取响应
  155. // 获取网页编码,我们只需要测试查找前4096个字节,一般编码信息都会在里面找到
  156. String temp = new String(this.bytes, 0,
  157. bytes.length < 4096 ? bytes.length : 4096);
  158. mat = Pattern.compile("(?<=<meta.{0,100}?charset=)[a-z-0-9]*",
  159. Pattern.CASE_INSENSITIVE).matcher(temp);
  160. if (mat.find()) {
  161. this.charset = mat.group();
  162. } else {
  163. this.charset = CHARSET_DEFAULT;
  164. }
  165. // 用正确的编码得到网页报头和内容
  166. temp = new String(this.bytes, this.charset);
  167. int headerEnd = temp.indexOf(CONTENT_SEPARATOR);
  168. this.header = temp.substring(0, headerEnd);
  169. this.content = temp.substring(headerEnd + CONTENT_SEPARATOR.length(),
  170. temp.length());
  171. socket.close(); // 关闭socket
  172. }
  173. /**
  174. * 根据网址,获取服务器地址<br/>
  175. * 例如:<br/>
  176. * http://m.weathercn.com/common/province.jsp
  177. * <p>
  178. * 返回:<br/>
  179. * m.weathercn.com
  180. *
  181. * @param url
  182. *            网址
  183. * @return
  184. */
  185. public static String getHostUrl(String url) {
  186. String host = "";
  187. Matcher mat = Pattern.compile("(?<=https?://).+?(?=/)").matcher(url);
  188. if (mat.find()) {
  189. host = mat.group();
  190. }
  191. return host;
  192. }
  193. /**
  194. * 根据网址,获取网页路径 例如:<br/>
  195. * http://m.weathercn.com/common/province.jsp
  196. * <p>
  197. * 返回:<br/>
  198. * /common/province.jsp
  199. *
  200. * @param url
  201. * @return 如果没有获取到网页路径,返回"";
  202. */
  203. public static String getSubUrl(String url) {
  204. String subUrl = "";
  205. Matcher mat = Pattern.compile("https?://.+?(?=/)").matcher(url);
  206. if (mat.find()) {
  207. subUrl = url.substring(mat.group().length());
  208. }
  209. return subUrl;
  210. }
  211. /**
  212. * 将b1和b2两个byte数组拼接成一个, 结果=b1+b2
  213. *
  214. * @param b1
  215. * @param b2
  216. * @return
  217. */
  218. public static byte[] ByteArrayCat(byte[] b1, byte[] b2) {
  219. byte[] b = new byte[b1.length + b2.length];
  220. System.arraycopy(b1, 0, b, 0, b1.length);
  221. System.arraycopy(b2, 0, b, b1.length, b2.length);
  222. return b;
  223. }
  224. /**
  225. * 读取输入流并转为byte数组,不返回字符串, 是因为输入流的编码不确定,错误的编码会造成乱码。
  226. *
  227. * @param is
  228. *            输入流inputstream
  229. * @return 字符串
  230. * @throws IOException
  231. */
  232. public static byte[] InputStream2ByteArray(InputStream is)
  233. throws IOException {
  234. byte[] b = new byte[0];
  235. byte[] bb = new byte[4096]; // 缓冲区
  236. int len = 0;
  237. while ((len = is.read(bb)) != -1) {
  238. byte[] newb = new byte[b.length + len];
  239. System.arraycopy(b, 0, newb, 0, b.length);
  240. System.arraycopy(bb, 0, newb, b.length, len);
  241. b = newb;
  242. }
  243. return b;
  244. }
  245. }

DictMain.java

[java] view plaincopy
  1. package com.siqi.dict;
  2. import java.io.File;
  3. import java.io.FileReader;
  4. import java.io.FileWriter;
  5. import java.io.IOException;
  6. import java.util.regex.Matcher;
  7. import java.util.regex.Pattern;
  8. /**
  9. * 从汉典下载汉字网页,并提取拼音信息
  10. * @author siqi
  11. *
  12. */
  13. public class DictMain {
  14. /**
  15. * 网页保存路径
  16. */
  17. public static final String SAVEPATH = "dict/pages/";
  18. /**
  19. * 下载的汉字网页名称
  20. */
  21. public static final String FILEPATH = SAVEPATH + "%s.html";
  22. /**
  23. * 字典数据文件名称
  24. */
  25. public static final String DATA_FILENAME = "data.txt";
  26. /**
  27. * 汉字unicode最小
  28. */
  29. public static final int UNICODE_MIN = 0x4E00;
  30. /**
  31. * 汉字unicode最大
  32. */
  33. public static final int UNICODE_MAX = 0x9FFF;
  34. /**
  35. * 准备工作:
  36. * 1.从汉典网站下载所有汉字的页面,注意,不要在eclipse中打开保存页面的文件夹,
  37. * 因为每个汉字一个页面,总共有20000+个页面,容易卡死eclipse
  38. * 2.从汉字页面获取汉字拼音信息,生成data.dat文件
  39. * 3.生成的data.dat复制到com.siqi.pinyin下面
  40. * 4.可以使用com.siqi.pinyin.PinYin.java了
  41. */
  42. static{
  43. // 下载网页
  44. for (int i = UNICODE_MIN; i <= UNICODE_MAX; i++) {
  45. // 检查是否已经存在
  46. String filePath = String.format(FILEPATH, i); // 文件名
  47. File file = new File(filePath);
  48. if (!file.exists()) {
  49. new DownloadThread(i).start();
  50. }
  51. }
  52. //解析网页,得到拼音信息,并保存到data.dat
  53. StringBuffer sb = new StringBuffer();
  54. for (int i = UNICODE_MIN; i <= UNICODE_MAX; i++) {
  55. String word = new String(Character.toChars(i));
  56. String pinyin = getPinYinFromWebpageFile(String.format(FILEPATH, i));
  57. String str = String.format("%s,%s,%s\r\n", i,word,pinyin);
  58. System.out.print(str);
  59. sb.append(str);
  60. }
  61. //保存到data.dat
  62. try {
  63. FileWriter fw = new FileWriter(DATA_FILENAME);
  64. fw.write(sb.toString());
  65. fw.close();
  66. } catch (IOException e) {
  67. e.printStackTrace();
  68. }
  69. }
  70. public static void main(String[] args){
  71. System.out.println("All prepared!");
  72. }
  73. /**
  74. * 从网页文件获取拼音信息
  75. * @param file
  76. * @return
  77. */
  78. private static String getPinYinFromWebpageFile(String file) {
  79. try {
  80. char[] buff = new char[(int) new File(file).length()];
  81. FileReader reader = new FileReader(file);
  82. reader.read(buff);
  83. reader.close();
  84. String content = new String(buff);
  85. // spf("yi1")
  86. Matcher mat = Pattern.compile("(?<=spf\\(\")[a-z1-4]{0,100}",
  87. Pattern.CASE_INSENSITIVE).matcher(content);
  88. if (mat.find()) {
  89. return mat.group();
  90. }
  91. //<span class="dicpy">cal</span> spf("xin1")
  92. mat = Pattern.compile("(?<=class=\"dicpy\">)[a-z1-4]{0,100}",
  93. Pattern.CASE_INSENSITIVE).matcher(content);
  94. if (mat.find()) {
  95. return mat.group();
  96. }
  97. } catch (Exception e) {
  98. e.printStackTrace();
  99. }
  100. return "";
  101. }
  102. }

DownloadThread.java

[java] view plaincopy
  1. package com.siqi.dict;
  2. import java.io.File;
  3. import java.io.FileWriter;
  4. import java.net.URLEncoder;
  5. import java.util.regex.Matcher;
  6. import java.util.regex.Pattern;
  7. import com.siqi.http.Httpclient;
  8. /**
  9. * 将汉字页面从汉典网站下载下来,存储到本地
  10. * http://www.zdic.net/search/?c=2
  11. * @author siqi
  12. *
  13. */
  14. public class DownloadThread extends Thread{
  15. /**
  16. * 线程最大数目
  17. */
  18. public static int THREAD_MAX = 10;
  19. /**
  20. * 下载最大重复次数
  21. */
  22. public static int RETRY_MAX = 5;
  23. /**
  24. * 汉典网站搜索网址
  25. */
  26. public static String SEARCH_URL = "http://www.zdic.net/search/?q=%s";
  27. /**
  28. * 当前线程数目
  29. */
  30. private static int threadCnt = 0;
  31. /**
  32. * 当前线程处理汉字的unicode编码
  33. */
  34. private int unicode = 0;
  35. /**
  36. * 如果PATH文件夹不存在,那么创建它
  37. */
  38. static{
  39. try {
  40. File file = new File(DictMain.SAVEPATH);
  41. if (!file.exists()) {
  42. file.mkdirs();
  43. }
  44. } catch (Exception e) {
  45. }
  46. }
  47. /**
  48. * 返回当前线程数量
  49. * @param i 修改当前线程数量 threadCnt += i;
  50. * @return 返回修改后线程数量
  51. */
  52. public static synchronized int threadCnt(int i){
  53. threadCnt += i;
  54. return threadCnt;
  55. }
  56. /**
  57. * 下载UNICODE编码为unicode的汉字网页
  58. * @param unicode
  59. */
  60. public DownloadThread(int unicode){
  61. //等待,直到当前线程数量小于THREAD_MAX
  62. while(threadCnt(0)>THREAD_MAX){
  63. try {
  64. Thread.sleep(500);
  65. } catch (InterruptedException e) {
  66. }
  67. }
  68. threadCnt(1);   //线程数量+1
  69. this.unicode = unicode;
  70. }
  71. @Override
  72. public void run() {
  73. long t1 = System.currentTimeMillis(); // 记录时间
  74. String filePath = String.format(DictMain.FILEPATH, unicode); // 文件名
  75. String word = new String(Character.toChars(unicode)); // 将unicode转换为数字
  76. boolean downloaded = false;
  77. int retryCnt = 0; // 下载失败重复次数
  78. while (!downloaded && retryCnt < RETRY_MAX) {
  79. try {
  80. String content = DownloadPage(word);
  81. SaveToFile(filePath, content);
  82. downloaded = true;
  83. threadCnt(-1);
  84. System.out.println(String.format("%s, %s, 下载成功!线程数目:%s 用时:%s",
  85. unicode, word, threadCnt(0), System.currentTimeMillis()
  86. - t1));
  87. return;
  88. } catch (Exception e) {
  89. retryCnt++;
  90. }
  91. }
  92. threadCnt(-1);
  93. System.err.println(String.format("%s, %s, 下载失败!线程数目:%s 用时:%s", unicode,
  94. word, threadCnt(0), System.currentTimeMillis() - t1));
  95. }
  96. /**
  97. * 在汉典网站上查找汉字,返回汉字字典页面内容
  98. * @param word
  99. * @return
  100. * @throws Exception
  101. */
  102. public String DownloadPage(String word) throws Exception{
  103. //查找word
  104. Httpclient httpclient = new Httpclient();
  105. String url = String.format(SEARCH_URL, URLEncoder.encode(word, "UTF-8"));
  106. httpclient.processUrl(url, Httpclient.METHOD_POST);
  107. //返回的是一个跳转页
  108. //获取跳转的链接
  109. Matcher mat = Pattern.compile("(?<=HREF=\")[^\"]+").matcher(httpclient.getContent());
  110. if(mat.find()){
  111. httpclient.processUrl(mat.group());
  112. }
  113. return httpclient.getContent();
  114. }
  115. /**
  116. * 将内容content写入file文件
  117. * @param file
  118. * @param content
  119. */
  120. public void SaveToFile(String file, String content){
  121. try {
  122. FileWriter fw = new FileWriter(file);
  123. fw.write(content);
  124. fw.close();
  125. } catch (Exception e) {
  126. e.printStackTrace();
  127. }
  128. }
  129. }

PinYin.java

[java] view plaincopy
  1. package com.siqi.pinyin;
  2. import java.io.BufferedReader;
  3. import java.io.InputStreamReader;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. public class PinYin {
  7. private static Map<Integer, PinYinEle> map = new HashMap<Integer, PinYinEle>();
  8. /**
  9. * 载入pinyin数据文件
  10. */
  11. static {
  12. try {
  13. BufferedReader bReader = new BufferedReader(new InputStreamReader(
  14. PinYin.class.getResourceAsStream("data.dat")));
  15. String aLine = null;
  16. while ((aLine = bReader.readLine()) != null) {
  17. PinYinEle ele = new PinYinEle(aLine);
  18. map.put(ele.getUnicode(), ele);
  19. }
  20. bReader.close();
  21. } catch (Exception e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. /**
  26. * 去掉注释可以测试一下
  27. *
  28. * @param args
  29. */
  30. public static void main(String[] args) {
  31. System.out.println(" 包含声调:" + PinYin.getPinYin("大家haome12345"));
  32. System.out.println("不包含声调:" + PinYin.getPinYin("大家haome12345", false));
  33. }
  34. /**
  35. * 获取汉字字符串的拼音,containsNumber是否获取拼音中的声调1、2、3、4
  36. *
  37. * @param str
  38. * @param containsNumber
  39. *            true = 包含声调,false = 不包含声调
  40. * @return
  41. */
  42. public static String getPinYin(String str, boolean containsNumber) {
  43. StringBuffer sb = new StringBuffer();
  44. for (Character ch : str.toCharArray()) {
  45. sb.append(getPinYin(ch, containsNumber));
  46. }
  47. return sb.toString();
  48. }
  49. /**
  50. * 获取字符串的拼音
  51. *
  52. * @param str
  53. * @return
  54. */
  55. public static String getPinYin(String str) {
  56. StringBuffer sb = new StringBuffer();
  57. for (Character ch : str.toCharArray()) {
  58. sb.append(getPinYin(ch));
  59. }
  60. return sb.toString();
  61. }
  62. /**
  63. * 获取单个汉字的拼音,包含声调
  64. *
  65. * @param ch
  66. * @return
  67. */
  68. public static String getPinYin(Character ch) {
  69. return getPinYin(ch, true);
  70. }
  71. /**
  72. * 获取单个汉字的拼音
  73. *
  74. * @param ch
  75. *            汉字. 如果输入非汉字,返回ch. 如果输入null,返回空字符串;
  76. * @param containsNumber
  77. *            true = 包含声调,false = 不包含声调
  78. * @return
  79. */
  80. public static String getPinYin(Character ch, boolean containsNumber) {
  81. if (ch != null) {
  82. int code = ch.hashCode();
  83. if (map.containsKey(code)) {
  84. if (containsNumber) {
  85. return map.get(code).getPinyin();
  86. } else {
  87. return map.get(code).getPinyin().replaceAll("[0-9]", "");
  88. }
  89. } else {
  90. return ch.toString();
  91. }
  92. }
  93. return "";
  94. }
  95. }

PinYinEle.java

[java] view plaincopy
  1. package com.siqi.pinyin;
  2. public class PinYinEle {
  3. private int unicode;
  4. private String ch;
  5. private String pinyin;
  6. public PinYinEle(){}
  7. public PinYinEle(String str){
  8. if(str!=null){
  9. String[] strs = str.split(",");
  10. if(strs.length == 3){
  11. try{
  12. this.unicode = Integer.parseInt(strs[0]);
  13. }catch(Exception e){
  14. }
  15. this.ch = strs[1];
  16. this.pinyin = strs[2];
  17. }
  18. }
  19. }
  20. public int getUnicode() {
  21. return unicode;
  22. }
  23. public void setUnicode(int unicode) {
  24. this.unicode = unicode;
  25. }
  26. public String getCh() {
  27. return ch;
  28. }
  29. public void setCh(String ch) {
  30. this.ch = ch;
  31. }
  32. public String getPinyin() {
  33. return pinyin;
  34. }
  35. public void setPinyin(String pinyin) {
  36. this.pinyin = pinyin;
  37. }
  38. }

生成的data.dat里面内容(部分)为:

[java] view plaincopy
  1. 19968,一,yi1
  2. 19969,丁,ding1
  3. 19970,丂,kao3
  4. 19971,七,qi1
  5. 19972,丄,shang4
  6. 19973,丅,xia4
  7. 19974,丆,han3
  8. 19975,万,wan4
  9. 19976,丈,zhang4
  10. 19977,三,san1
  11. 19978,上,shang4
  12. 19979,下,xia4
  13. 19980,丌,qi2
  14. 19981,不,bu4

运行DictMain.java结果

执行时间可能会有几十分钟到几小时不等,总共会下载200+M的网页(20000+个网页),每次运行都会先判断以前下载过没有,所以结束掉程序不会有影响

显示All prepared!表示已经准备好了,刷新项目文件夹,可以看到网页保持在dict/pages下面,不建议在elipse中打开那个文件夹,因为里面有2万多个文件,会卡死eclipse,

还可以看到生成了data.txt文件,改为data.dat并复制到pinyin文件夹下面

运行PinYin.java

可以看到"大家haome12345"的拼音:

[java] view plaincopy
  1. 包含声调:da4jia1haome12345
  2. 包含声调:dajiahaome12345

上面只是显示了如何获取拼音,获取笔画等的方法类似,在这里就不演示了。

java实现汉字字典相关推荐

  1. java 汉字字典,获取汉字拼音,拼音首字母,五笔,笔画,笔画顺序

    最新的可以下载的包(原来写的丢失了,重新写了个): http://download.csdn.net/detail/wssiqi/6394057 如果地址不可访问,查看我的资源,看还在不.~~~ 环境 ...

  2. java 实现汉字转换拼音_JAVA实现汉字转拼音功能代码实例

    JAVA中汉字转拼音的方法并不复杂,可以使用pinyin4j包来实现. 一.下载pinyin4j的架包,并导入项目中,如下: 如果是maven项目,maven依赖如下: com.belerweb pi ...

  3. JAVA实现汉字转换为拼音 pinyin4j/JPinyin

    转载自  JAVA实现汉字转换为拼音 pinyin4j/JPinyin 在项目中经常会遇到需求用户输入汉字后转换为拼音的场景,比如说通讯录,就会要求按名字首字符发音排序,如果自己写实现这方面的功能是个 ...

  4. java单词按字典排序_最终Java日志字典:开发人员最常记录的单词是什么?

    java单词按字典排序 最终的记录字典,或者:我们记录的最常见单词是什么? 日志文件是调试应用程序的最常用方法,当解决错误时,它们肯定可以引导我们朝正确的方向发展. 但是,大多数日志文件每天都会增加一 ...

  5. java实现汉字转为拼音

    java实现汉字转为拼音: 1.需要导入pinyin4j.jar package com.loo.pinyin; import net.sourceforge.pinyin4j.PinyinHelpe ...

  6. java把汉字转换成拼音_Java实现汉字转换为拼音

    本文的核心代码取自easydozer的blog:http://blog.csdn.net/easydozer/ 代码说明: Java实现汉字转换为拼音的GUI版本. GUI代码部分: /** * @( ...

  7. java 实现汉字转换拼音_Java实现汉字转换为拼音

    # re: Java实现汉字转换为拼音 2006-11-24 15:06 芦苇 JAVA将汉字转化成拼音的方法 /** *//** ################################## ...

  8. Java将汉字转换为全拼

    Java将汉字转换为全拼 pom依赖 <dependency><groupId>com.belerweb</groupId><artifactId>pi ...

  9. Java比较汉字字符串排序与C++比较汉字排序

    一.Java比较汉字 // Collator 类是用来执行区分语言环境的 String 比较的,这里选择使用CHINA Comparator cmp = Collator.getInstance(ja ...

最新文章

  1. 磁盘调度算法java代码
  2. 牛客 - 求函数(线段树+区间合并/线段树+矩阵维护)
  3. 阿里开发者招聘节 | 面试题02-04:给定一个二叉搜索树(BST),找到树中第K小的节点
  4. java读c二进制文件_如何使用JAVA读取C / Matlab创建的二进制文件
  5. oracle安装 衍生进程已退出,linux安装oracle 出现问题
  6. 固件升级_洛达1562a固件升级支持空间音频
  7. 关于unique()的详解
  8. JavaScript提高:006:ASP.NET使用easyUI TABS标签updatepanel
  9. 顺序存储循环队列的基本操作
  10. 基于matlab的暴雨强度公式参数推求,基于MATLAB的暴雨强度公式参数推求
  11. oracle sqlldr decode,sqlldr时遇到的一个问题
  12. 中国移动校招面试( 计算机、大数据、通信专业相关岗位)一面
  13. 【2022年第十周周总结】拖延症啊。。。。算法题啊。。。。
  14. 服务器日志法网站分析的原理及优缺点
  15. Android---ADB工具连接真实手机(有线连接与无线连接)
  16. 高速公路交警的经验之谈[转自QQ群]
  17. 机器人操作系统 ROS 相关书籍整理合集 [古月居推荐]
  18. java设计模式简化版之六大原则
  19. Facebook的23岁创始人
  20. 2018.12.30【NOIP提高组】模拟A组 JZOJ 5353 村通网

热门文章

  1. matlab 从 wind 量化接口获取数据
  2. 肃宁的车随身WiFi是中兴微的芯片,可以切换自己卡上网
  3. PS插件Photolemur 3 1.1.AI人工智能全自动中文版 支持CC2019
  4. 如何用电脑反编译微信小程序,获得源码(学习用途)
  5. 获取千千静听歌词下载地址(Delphi) 源码+Demo发布
  6. C# winform 实习语音播报
  7. Android自定义View,实现全屏滑动的DrawerLayout
  8. 我为什么那么喜欢《宫崎骏の电影》
  9. 支持中国信用卡网购的海外好网店(希望各位坛友补充)
  10. 短链接生成平台哪个好用