解碼百度輸入法詞庫


    最近需要解析下載得到的百度輸入法詞庫,本來嘗試利用深藍詞庫轉換解決,無奈深藍詞庫不能對各個路徑下的詞庫分別進行處理,只能進行合並操作,這就喪失了原來路徑具有的分類信息。看來這個坑還得自己填。

    聲明:下述沒有處理拼音,只是簡單的提取詞庫中的中文詞。
    需要處理詞庫,前提條件是了解詞庫文件內部存放方式。根據深藍詞庫轉換源碼,我們可以推出百度詞庫編碼方式如下:
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);
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM