如何判断一个文本文件的编码

mac2022-06-30  58

检测策略

如果2个字节是0xFF 0xFE,则以Unicode(LE)的方式读取如果2个字节是0xFE 0xFF,则以Unicode BE的方式读取如果前2个字节是0xEF 0xBB,那么判断第3个字节是不是0xBF,如果是的话就以UTF-8的方式进行读取。判断是否符合UTF-8的编码规范,如果符合就以UTF-8的方式进行读取如果以上都不是,则以ANSI的方式进行读取。

代码实现

首先,首先一个enum class作为检测的返回值

enum class Encode { ANSI = 1, UNICODE_LE, UNICODE_BE, UTF8, UTF8_NOBOM };

然后我们可以根据上面总结的规律进行判断。

Encode DetectEncode(const PBYTE pBuffer, long length) { if (pBuffer[0] == 0xFF && pBuffer[1] == 0xFE) { return Encode::UNICODE_LE; } else if (pBuffer[0] == 0xFE && pBuffer[1] == 0xFF) { return Encode::UNICODE_BE; } else if (pBuffer[0] == 0xEF && pBuffer[1] == 0xBB && pBuffer[2] == 0xBF) { return Encode::UTF8; } else if (CheckUnicodeWithoutBOM(pBuffer, length)) { return Encode::UTF8_NOBOM; } else { return Encode::ANSI; } }

下面附上如何检测UTF-8 without BOM的代码实现。

BOOL CheckUnicodeWithoutBOM(const PBYTE pText, long length) { int i; DWORD nBytes = 0; UCHAR chr; BOOL bAllAscii = TRUE; for (i = 0; i < length; i++) { chr = *(pText + i); if ((chr & 0x80) != 0) bAllAscii = FALSE; if (nBytes == 0) { if (chr >= 0x80) { if (chr >= 0xFC && chr <= 0xFD) nBytes = 6; else if (chr >= 0xF8) nBytes = 5; else if (chr >= 0xF0) nBytes = 4; else if (chr >= 0xE0) nBytes = 3; else if (chr >= 0xC0) nBytes = 2; else { return FALSE; } nBytes--; } } else { if ((chr & 0xC0) != 0x80) { return FALSE; } nBytes--; } } if (nBytes > 0) { return FALSE; } if (bAllAscii) { return FALSE; } return TRUE; }

参考资料

The Notepad encoding detection issues keep coming up简析Windows Notepad里可选的字符编码字符编码笔记:ASCII,Unicode和UTF-8字符集和字符编码(Charset & Encoding)Some code to detect charset (for XML, in Java)How can I detect the encoding/codepage of a text file

转载于:https://www.cnblogs.com/lkpp/p/encoding_detection.html

最新回复(0)