最近需要解析下載得到的百度輸入法詞庫,本來嘗試利用深藍詞庫轉換解決,無奈深藍詞庫不能對各個路徑下的詞庫分別進行處理,只能進行合並操作,這就喪失了原來路徑具有的分類信息。看來這個坑還得自己填。
聲明:下述沒有處理拼音,只是簡單的提取詞庫中的中文詞。
需要處理詞庫,前提條件是了解詞庫文件內部存放方式。根據深藍詞庫轉換源碼,我們可以推出百度詞庫編碼方式如下:
0x350 :詞庫存放開始位置
int len 詞語的長度,int數 4字節
長度2*len字節,對應拼音信息
長度2*len字節,對應unicode編碼的中文詞
所以,取出詞庫中的中文詞,只需首先將文件讀指針移動到0x350位置,讀取詞的長度,然后跳過中間的拼音信息,直接取到中文詞unicode編碼的字符串,然后對其進行解碼即可。取出文件中的所有詞語,只需要循環這個過程,直至文件讀指針到了文件末尾。在我的需求中,需要把轉碼的中文詞寫入到文件中。
思路說完了,下面上代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace read_file { class Program { public static int ReadInt32(Stream fs) { var temp = new byte[4]; fs.Read(temp, 0, 4); int s = BitConverter.ToInt32(temp, 0); return s; } public static List<String> readWord(string path,List<String>list) { var fs = new FileStream(path, FileMode.Open, FileAccess.Read); fs.Seek(0, SeekOrigin.End); long endPosition = fs.Position; fs.Position = 0x350; do { int len = ReadInt32(fs); fs.Position += len * 2; var temp = new byte[len * 2]; fs.Read(temp, 0, len * 2); String word = Encoding.Unicode.GetString(temp); list.Add(word); } while (fs.Position <endPosition-1); fs.Close(); return list; } static void transform_txt(string path) { var files = Directory.GetFiles(path, "*.bdict"); List<String> list = new List<string>(); foreach (var file in files) { list = readWord(file, list); Console.WriteLine(file + "文件處理完畢!"); } FileStream fs = new FileStream(path + "dict.txt", FileMode.Append); StreamWriter writer = new StreamWriter(fs, Encoding.UTF8); foreach (String word in list) { writer.Write(word + "\n"); } writer.Close(); fs.Close(); } static void Main(string[] args) { string []paths = { "C:FileRecv\\安徽\\" }; foreach (string path in paths) transform_txt(path); } } }