利用js判断文件是否为utf-8编码

使用FileReader以utf-8格式读取文件,根据文件内容是否包含乱码字符�,来判断文件是否为utf-8。

如果存在�,即文件编码非utf-8,反之为utf-8。

代码如下:

const isUtf8 = async (file: File) => {
return await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsText(file);

reader.onloadend = (e: any): void => {
  const content = e.target.result;
  const encodingRight = content.indexOf("") === -1;

  if (encodingRight) {
    resolve(encodingRight);
  } else {
    reject(new Error("编码格式错误,请上传 UTF-8 格式文件"));
  }
};

reader.onerror = () => {
  reject(new Error("文件内容读取失败,请检查文件是否损坏"));
};

});
};
该方法问题在于,如果文件非常大,比如几个G,浏览器读到的内容直接放在内存中,fileReader实例会直接触发onerror,抛出错误,有时浏览器会直接崩溃。

大文件方案
对于大文件,可以对文件内容进行抽样,对文件进行切片,这里使用100片。对切出的每片文件再切取前面1kb大小的片段,以string方式读取。如果1024B可能正好切在某个汉字编码的中间,导致以string方式读取时出错,即首尾可能出现�,被认为是非utf-8片段。这时可以取1kb对应字符串的前半段,再去判断�是否存在。

上述常数可以根据需求进行调整。

代码如下:

const getSamples = (file: File) => {
const filesize = file.size;
const parts: Blob[] = [];
if (filesize < 50 * 1024 * 1024) {
parts.push(file);
} else {
let total = 100;
const sampleSize = 1024 * 1024;
const chunkSize = Math.floor(filesize / total);
let start = 0;
let end = sampleSize;
while (total > 1) {
parts.push(file.slice(start, end));
start += chunkSize;
end += chunkSize;
total–;
}
}
return parts;
};

const isUtf8 = (filePart: Blob) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();

fileReader.readAsText(filePart);

fileReader.onload = (e) => {
  const str = e.target?.result as string;
  // 大致取一半
  const sampleStr = str?.slice(4, 4 + str?.length / 2);
  if (sampleStr.indexOf("�") === -1) {
    resolve(void 0);
  } else {
    reject(new Error(编码格式错误,请上传 UTF-8 格式文件"));
  }
};

fileReader.onerror = () => {
  reject(new Error(文件内容读取失败,请检查文件是否损坏"));
};

});
};

export default async function (file: File) {
const samples = getSamples(file);
let res = true;

for (const filePart of samples) {
try {
await isUtf8(filePart);
} catch (error) {
res = false;
break;
}
}
return res;
}
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值