ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-06-26 10:03:10  阅读:175  来源: 互联网

标签:编码 const 文件 reject js file new utf


常规方案

使用 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,抛出错误,有时浏览器会直接崩溃。

https://www.98891.com/article-68-1.html

大文件方案

对于大文件,可以对文件内容进行抽样,对文件进行切片,这里使用 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;
}

标签:编码,const,文件,reject,js,file,new,utf
来源: https://www.cnblogs.com/moluy/p/14933462.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有