前端判断txt文件是否为utf-8编码

Posted suedarsam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端判断txt文件是否为utf-8编码相关的知识,希望对你有一定的参考价值。

es6之前,这件事只能丢给后端解决。

现在要尽善尽美地解决这件事情,还是得靠后端,因为后端可以读取BOM头。

Q: 什么是BOM头?

A: 类似WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM)。它是一串隐藏的字符,用于让记事本等编辑器识别这个文件是否以UTF-8编码。对于 GBK,ANSI,UTF-8 格式的文件,第一个字符会是 0-9a-zA-Z-/. 之一

但是有一种情况可以由前端去判断,什么情况呢,就是我们只需要区分该TXT文件是UTF8还是UTF16的编码格式,并且该UTF8文件的第一个字符不是除了ASCII码表的其他字符,因为这些字符在UTF8编码的文件中为一个字节长度。
(字节、字符和编码的关系戳这里)

这种情况下,就可以采用本文所介绍的方法,当然了,最好还是前后端一齐检验逻辑比较严密。

先来看一些概念:

然后看一张字节表。


(图来自hongda: 字符,字节和编码)

由表可知,在UTF8的编码下,英文字符的字节数是1,而UTF16,英文字符的字节数则是大于1的数,也就是说,我们可以通过Uint8Array读取第一个字节,判断其是否是字符,来判断其是否是UTF8编码的文件。这也是这个方法的局限点,因为有些字符是两个字节编码的,我们无法通过判断第一个字节,将文件确定为UTF8编码格式。

将文件用二进制格式读取后,采用TypedArrayUint8Array进行转换,而读出来是ASCII码,根据ASCII和字符的对应表进行判断即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hKY9Yqa2-1586421199525)(https://user-gold-cdn.xitu.io/2020/4/8/1715a048fc0bf70a?w=1260&h=1240&f=png&s=368183)]

/**
 * @description: 二进制形式读取txt文件 并判断其是否为utf-8
 * @param type
 * @return:
 */
function readFile(file) 
    return new Promise((resolve, reject) => 
        const reader = new FileReader();
        reader.onload = function (evt) 
            resolve(evt.target.result);
        ;
        reader.readAsArrayBuffer(file);
    );


export const isUtf8 = async function (file) 
    let res = await readFile(file);
    let firstCode = new Uint8Array(res)[0];
    return firstCode >= 33 && firstCode <= 126;
;

以上是关于前端判断txt文件是否为utf-8编码的主要内容,如果未能解决你的问题,请参考以下文章

如何检查TXT文本是否ANSI编码格式的?

没有文件头的txt文件,如何判断是啥编码格式

怎么辨别文本文档的编码?

windows设置新建文本文档默认编码UTF-8

文件-读取与编码检测

为啥kafka接收的中文变成了unicode编码,怎么解决