C# C流读取器不区分UTF-16和UTF-8

C# C流读取器不区分UTF-16和UTF-8,c#,utf-8,C#,Utf 8,我正在构建一个应用程序,从电子邮件服务器下载一个纯文本的csv文件,并将其写入本地文件系统。我正在使用.NET Core 3.1在C中开发此应用程序 问题是我不知道我接收的文件的编码是什么,所以我决定使用StreamReader类将我从电子邮件下载的字节转换为字符串 这是密码 foreach (var data in loadedData) { if (IsValidData(data)) { logger.Info($"Writing data fro

我正在构建一个应用程序,从电子邮件服务器下载一个纯文本的csv文件,并将其写入本地文件系统。我正在使用.NET Core 3.1在C中开发此应用程序

问题是我不知道我接收的文件的编码是什么,所以我决定使用StreamReader类将我从电子邮件下载的字节转换为字符串

这是密码

foreach (var data in loadedData)
{
    if (IsValidData(data))
    {
        logger.Info($"Writing data from: {data.FileName}");

        using var stream = new MemoryStream(data.FileContent);
        using var reader = new StreamReader(stream, true);

        var csvData = new CSVData
        {
            FileName = data.FileName,
            FileContent = reader.ReadToEnd(),
        };
        dataWriter.WriteData(csvData);
        logger.Info($"Writing data from: {data.FileName} was successfully written");
    }
    else
    {
        logger.Warn($"Invalid format: {data.FileName}");
    }
}
并将数据写入我正在使用的实际文件:

public void WriteData(CSVData data)
{
    logger.Debug($"Writing received file: {data.FileName}");

    var outputDir = config.GetReceivedFilesPath();
    string fileName = this.GetOutputPath(data.FileName, outputDir);

    Directory.CreateDirectory(outputDir);
    using var writer = new StreamWriter(fileName, false, Encoding.UTF8);
    writer.Write(data.FileContent);
    logger.Debug($"The received data was successfully written to: {data.FileName}");
}
问题是,我正在接收的一些文件是用UTF-16编码的。我相信这是正在使用的编码,因为每个字符后面都有一个\0,但是StreamReader将此文件解释为用UTF-8编码的,因为reader.CurrentEncoding属性返回UTF-8

最终的结果是,我的应用程序没有将我的文件输出为UTF-8,而是将它们输出为UTF-16,尽管我明确地添加了UTF-8作为输出值


我做错了什么?

您可以使用此方法

File.ReadAllTextstring路径,System.Text.Encoding

根据文档,它试图自动解决这个问题。 以下文本来自文档

此方法打开一个文件,读取文件中的所有文本,然后返回 它就像一根绳子。然后关闭该文件

此方法尝试自动检测文件的编码 基于字节顺序标记的存在。编码格式UTF-8和 UTF-32可以检测到大端和小端

此方法保证关闭文件句柄,即使 提出了例外情况

要使用为操作系统配置的编码设置, 指定编码参数的Encoding.Default属性


可以找到完整的文档

如果存在BOM,它只能检测UTF-16。data.FileContent的前4个字节是什么?文档说明,除非另有规定,否则StreamReader始终默认为UTF-8,因此您必须自己进行检测,然后将正确的编码传递给读取器的构造函数。首先需要找到传入文件的编码。前4个字节中的组合可以说明存在什么编码。有很多例子。StreamReader未检测到正确的编码。如果没有提到,它只使用默认值。一旦知道了编码,您就可以在StreamReader中使用它。@EtienDemartel:文档说明StreamReader总是默认为UTF-8-文档有误导性。是的,使用的默认编码是UTF8。但如果找到,StreamReader将遵守UTF16或UTF8 BOM指定的编码,除非使用具有detectEncodingFromByteOrderMarks参数的构造函数,对于该参数的值,将传递false。StreamReader将此文件解释为UTF-8编码的文件-StreamReader正确解码UTF16输入的唯一方法是,如果输入的前两个字节包含UTF16 BOM,或者通过向构造函数传递Encoding.Unicode显式告诉它。如果两者都不适用,您将得到不正确的结果。改变这种情况的唯一方法是修复代码,以便输入的代码格式正确,即具有BOM表,或者明确创建StreamReader时要使用的编码。有关更多详细信息,请参见重复。ReadAllText遵循与StreamReader完全相同的启发式。这个答案绝不是对所问问题的解决办法。