chardet 判断 stream:bytes 的时候,要短,但是不能太短

越短越不准,越长越慢

判断一个 15MB 的 txt 文件,需要耗时 5-20 秒

所以,我建议,取前 256 个字节来判断,可以平衡速度和准确率

def check_encoding(stream: bytes) -> str | None:
    encoding = chardet.detect(stream[:256]).get('encoding', None)
    return encoding

这样(指取前 256 字节)大概只需要 10-30 ms 就可以判断出文件编码


还有一个需要注意点:

就是一些明明是 gbk 编码的文件,chardet 会说是 gb2312 的。这会导致 decode 的时候报错,一些字符无法 decode

原因在于 gb2312 < gbk < gb18030

GB 2312 标准共收录 6763 个汉字
GBK 共收入 21886 个汉字和图形符号
GB 18030 与 GB 2312-1980 和 GBK 兼容,共收录汉字70244个
参考:GB2312、GBK、GB18030 这几种字符集的主要区别是什么?

gbk 是 gb2312 的超集,gb18030 又是 gbk 的超集

所以我会把 gb2312、gbk 都用 gb18030 替代,保证 100% 处理中国国标编码

def check_encoding(stream: bytes) -> str | None:
    encoding = chardet.detect(stream[:256]).get('encoding', None)
    if encoding.lower() == 'gb2312' or encoding.lower() == 'gbk':
        return 'gb18030'
    return encoding

universe_king
3.4k 声望680 粉丝