如何确定上传的文件是UTF-8还是UTF-16

本文关键字:UTF-8 还是 UTF-16 文件 何确定 | 更新日期: 2023-09-27 18:00:05

我有一个网站,用户可以在那里上传一个数据的txt文件,数据将被导入数据库。然而,一些用户以UTF-8上传数据,而另一些用户则以UTF-16上传数据。

    byte[] fileData = null;
    uploader.PostedFile.InputStream.Read(fileData, 0, length);
    data = TLCommon.EncodeJsString(System.Text.Encoding.UTF8.GetString(fileData));

当文件保存在UTF-16中并上传时,数据就是垃圾。我该如何处理这种情况?

如何确定上传的文件是UTF-8还是UTF-16

您可以使用各种启发式方法,例如检查流中00字节的高百分比。(这些不会出现在UTF-8中,但在包含ASCII字符的UTF-16文本中很常见。)

然而,这并不能区分UTF-8和Windows-1252,它们是不兼容的8位编码,在美国英语Windows系统中都很常见。您可以添加更多的检查,例如查找在一种编码中无效但在另一种编码下无效的字节序列,但这开始变得非常复杂,通常无法区分不同的单字节编码。

微软提供了一个名为MLang的库,它可以通过对流中字节的统计分析来自动检测UTF-8、UTF-16和许多8位代码页。如果它有足够大的文本样本来处理,那么它的准确性就相当好。我在博客中介绍了如何使用这种方法,并在GitHub上发布了完整的源代码。

您可以使用以下几个选项:检查内容类型,看看它是否包括指示编码的字符集参数(例如Content-Type: text/plain; charset=utf-16);检查上传的数据是否有BOM(文件中的前几个字节,它将映射到unicode字符U+FEFF-UTF-16为2个字节,UTF-8为3个字节),或者如果您对文件有所了解(第一个字符应该是ascii,例如在XML中,以'<'开头),则可以使用它来查找编码。但如果你没有这些信息,你就必须使用一些启发式方法来猜测。