檔案編碼檢測.ZC一些資料
1、IMultiLanguage3 或者 IMultiLanguage2
1.1、怎麼判斷XML 的編碼格式(UTF-8或GB2312等)-CSDN論壇.html(https://bbs.csdn.net/topics/391919768)
1.2、檢視當前編碼(內碼表) - lslsyqyq的專欄 - CSDN部落格.html(https://blog.csdn.net/lslsyqyq/article/details/80858048)
1.3、測試程式碼:(vs08x86)
//#define _UNICODE 1 //#pragma warning(disable:4305 4309) #pragmawarning(disable:4309)//warning C4309: “初始化”: 截斷常量值 #pragma comment(lib,"ole32") #pragma comment(lib,"comsupp") #include <cstdio> #include <objbase.h> #include <comip.h> #include <mlang.h> #include <tchar.h> typedef _com_ptr_t<_com_IIID<IMultiLanguage3, &IID_IMultiLanguage3> > IMultiLanguage3Ptr;// https://bbs.csdn.net/topics/391919768 int main() { CoInitialize(NULL); { IMultiLanguage3Ptr pML(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC); //char data[] = { 0xD6, 0xD0, 0xCE, 0xC4, 0xB1, 0xE0, 0xC2, 0xEB }; //char data[] = { 0xD7, 0xB4, 0xCC, 0xAC, 0xCD, 0xBC, 0xD4, 0xAA };//, 0x74, 0x65, 0x73, 0x74 };char data[] = { 0xD7, 0xDD, 0x9C, 0xAB, 0xCD, 0xBB, 0xD4, 0xA9 }; int isize = sizeof(data); DetectEncodingInfo result[32]; int result_count = sizeof(result) / sizeof(result[0]); //HRESULT hr = pML->DetectInputCodepage(MLDETECTCP_NONE, 0, data, &isize, result, &result_count); HRESULT hr = pML->DetectInputCodepage(MLDETECTCP_NONE, 0, data, &isize, result, &result_count); if (!SUCCEEDED(hr)) { fprintf(stderr, "Failed with 0x%x\n", hr); CoUninitialize(); return hr; } for (int i = 0; i < result_count; i++) { WCHAR desc[100] = {0}; pML->GetCodePageDescription(result[i].nCodePage, result[i].nLangID, desc, 100); printf("CP:%d (%S)\n", result[i].nCodePage, desc); } } CoUninitialize(); // D7 B4 CC AC CD BC D4 AA system("pause"); return 0; }
下面是一個 GBK編碼的 中文字串的 char陣列資訊:
char data[] = { 0xD6, 0xD0, 0xCE, 0xC4, 0xB1, 0xE0, 0xC2, 0xEB };// 中文編碼 //char data[] = { 0xD7, 0xB4, 0xCC, 0xAC, 0xCD, 0xBC, 0xD4, 0xAA };// 狀態圖元 //char data[] = { 0xD7, 0xDD, 0xCC, 0xAB, 0xCD, 0xBB, 0xD4, 0xAA };// 縱太突元
1.4、IMultiLanguage2 interface (Windows) _ Microsoft Docs.html(https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741001%28v%3dvs.85%29)
1.5、IMultiLanguage2__DetectInputCodepage method (Windows) _ Microsoft Docs.html(https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa740986%28v%3dvs.85%29)
ZC:使用 IMultiLanguage2或IMultiLanguage3的DetectInputCodepage 來分析 "狀態圖元"、"縱太突元"的字元陣列,會分不清是 GB2312和UTF8 也是有原因的,∵ Windows自己就搞不清.. 嘗試 開啟Win7x64的記事本,輸入2個字"狀態",然後 CTRL+S儲存(預設儲存,不手動選擇字元編碼),然後再開啟記事本,發現裡面的資料是亂碼,然後 再"另存為" 此時看到 Windows自己識別出來的編碼是"UTF-8",可見 Windows自己都分不清楚 GBK 和 不規範的UTF8 編碼...
2、
3、
4、Java的相關資料:
4.1、Java讀取檔案,判斷是否UTF-8的解決方案 - 墨的部落格 - CSDN部落格.html(https://blog.csdn.net/dreamworld204/article/details/79286793)
首先,UTF-8的編碼方式: 1位元組 0xxxxxxx 2位元組 110xxxxx 10xxxxxx 3位元組 1110xxxx 10xxxxxx 10xxxxxx 4位元組 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 5位元組 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 6位元組 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 實際上都在3位元組內,沒有遇到4位元組以上編碼的。根據其編碼格式我們就可以檔案進行一定的驗證了,例如:(ZC:後面是一段程式碼,這裡省略)
4.2、jchardet
ZC:前面嘗試 C/C++的chardet,感覺 好蛋疼難受... 查了下,發現 jchardet 卻是資料頗多 而且已經是別人從python翻譯過來弄好的 不需要自己編譯什麼的 用就行了
ZC:思路:可以將java的程式碼 封裝成 jar(它的檢測結果輸出到檔案中),然後 C/C++ 使用命令列方式執行這個jar 在命令列中讀取到jar寫入到了那個檔案的檔名(或使用固定路徑固定檔名),然後 C/C++再去讀取 jar的輸出檔案 (疑問:C/C++ 使用命令列方式執行這個jar,不會立即返回吧?應該是等jar執行完後再返回吧?)
ZC:下面 2篇文章還未細看:
(1)、字符集編碼的自動識別jchardet - 雲守護的專欄 - CSDN部落格.html(https://blog.csdn.net/earbao/article/details/38709701)
(2)、jChardet探測檔案字元編碼-部落格-雲棲社群-阿里雲.html(https://yq.aliyun.com/articles/59514)
5、