如何在 Angular 8 中检测文件的字符集?

How to detect character set of a file in Angular 8?

我想知道如何在使用 FileReader Web 读取文件之前检测文件的字符集 API。在使用 fileReader.readAsText(file, "UTF-8") 读取文件之前,我需要知道文件字符集是什么,其中 "UTF-8" 目前对我来说是未知的。

是否有我可以与 Angular 一起使用的任何 npm 包或任何无需查看签名或使用 BOM 代码即可检测字符集的手动 Vanilla 方法(我 PC 上的文件保存在 ISO- 8859-1 或 UTF-8 具有相同的签名且无 BOM 代码)。

到目前为止我尝试使用的包是'encoding'、'chardet'和'encoding-japanese'。这些不适用于 Angular 8,因为它们是为与 Node.

一起使用而制作的

背景故事: 我有一个 CSV,一旦它保存在 Excel 中,它就会以 ISO-8859-1 的编码保存,我不能指望我所有的客户都使用特定的编码保存他们的文件(非技术头脑的人) .但是,其他客户端可能会使用 Notepad++,它将以 UTF-8 格式保存这些文件。我需要一种方法来确定用于停止字符的编码:“�”出现。

您可能需要使用 detect-character-encoding,这是一个外部 npm 模块,它将像这样为您完成工作。

const fs = require('fs');
const detectCharacterEncoding = require('detect-character-encoding');

const fileBuffer = fs.readFileSync('file.txt');
const charsetMatch = detectCharacterEncoding(fileBuffer);

console.log(charsetMatch);
// {
//   encoding: 'UTF-8',
//   confidence: 60
// }

您可以在 Angular 应用程序中使用 encoding-japanese 包。尝试以下

  1. 将包添加到 package.json 和 运行 npm install
{
  "dependencies": {
    ...,
    "encoding-japanese": "^1.0.30",
  }
}
  1. 在应用程序中使用包。

控制器

import { Component } from '@angular/core';
import { Observable, Subject } from 'rxjs';

declare const require: any;
export const Encoding = require('encoding-japanese');

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  encoding: string;

  constructor() { }

  onUpload(event: any) {
    this.detectEncoding(event.currentTarget.files[0]).subscribe(
      encoding => {
        console.log('File encoding is: ' + encoding);
        this.encoding = encoding;
      }
    );
  }

  private detectEncoding(file): Observable<string> {
    let result = new Subject<string>();

    const reader = new FileReader();
    reader.onload = (e) => {
      const codes = new Uint8Array(e.target.result as ArrayBuffer);
      const detectedEncoding = Encoding.detect(codes);
      result.next(detectedEncoding);
    };
    reader.readAsArrayBuffer(file);

    return result.asObservable();
  }
}

模板

<input type="file" (change)="onUpload($event)"/>
<ng-container *ngIf="encoding">
  <p>File encoding is: {{ encoding }}</p>
</ng-container>

编码检测机制源自 encoding-japanese 示例 here

  1. 然后您可以验证订阅内的编码
this.detectEncoding(event.currentTarget.files[0]).subscribe(
  encoding => {
    if (encoding === 'UTF8') {
      // encoding is UTF-8
    } else {
      // encoding isn't UTF-8
    }
  }
);
  1. 您可以检查以下编码字符串。
    • UTF32
    • UTF16
    • UTF16BE
    • UTF16LE
    • 二进制
    • ASCII
    • 日制
    • UTF8
    • EUCJP
    • SJIS
    • 统一码

工作示例:Stackblitz

除非您的输入文件真的非常小,否则我认为您应该查看 detect-file-encoding-and-language

我在我的 React 应用程序中使用它来检测字幕文件的字符集,然后再通过 FileReader Web 加载它们 API。

我是这样做的:

import languageEncoding from "detect-file-encoding-and-language";

function inputHandler(e) {
  const file = e.target.files[0];
  languageEncoding(file).then(fileInfo => console.log(fileInfo.encoding));  // UTF-8
}

当然,您必须安装它:

$ npm i detect-file-encoding-and-language