C#编码问题与CsvHelper

c# encoding issues with CsvHelper

var orders = new List<Order>();
....
orders.Add(...)


string csvstring;
using (var ms = new MemoryStream())
using (var wr = new StreamWriter(stream, Encoding.UTF8))
using (var csvWriter = new CsvWriter(wr, CultureInfo.InvariantCulture, false))
{
    

csvWriter.WriteRecords(orders);
    csvstring = Encoding.UTF8.GetString(stream.ToArray());
}

然后

sftp.WriteAllText(fileNameAbsolutePath, csvstring, Encoding.UTF8);

在 sftp 中创建的文件内容以“feff”开头。 " orders.csv: text/plain; 字符集=utf-8".

这是问题的第一部分。我正在寻找的是将此 UTF8 转换为 IS0-8859-1 作为 最终文件中预期的字符集是 IS0-8859-1。

也许我应该做这样的事情?

byte[] bytesSS = Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1"), Encoding.UTF8.GetBytes(csvstring));

string s1 = Encoding.GetEncoding("ISO-8859-1").GetString(bytesSS, 0, bytesSS.Length);

尝试 google 获取“<feff>”,但我完全不了解 BOM 的概念和解决此问题的方法。

我不知道您使用哪个 SFTP class,因为 .NET 本身没有 SFTP 客户端。我假设您使用 this one 只是因为它在 Google 搜索 sftp WriteAllText.

时排在第一位

如果要创建具有特定编码的文件,请在 StreamWriter 构造函数中指定它而不是 UTF8 :

using (var ms = new MemoryStream())
using (var wr = new StreamWriter(stream, Encoding.GetEncoding("ISO-8859-1")))
using (var csvWriter = new CsvWriter(wr, CultureInfo.InvariantCulture, false))
{    
    csvWriter.WriteRecords(orders);
}

另一方面,UTF8 和 Latin1(或任何代码页)对 0-127 范围内的字符使用完全相同的值。如果你只想发送英文文本,无论你使用哪种编码都不会有任何区别。如果实际需求是创建一个没有BOM的UTF8文件,可以使用合适的UTF8Encoding constructor :

来指定
var utf8NoBom=new UTF8Encoding(false);
using (var ms = new MemoryStream())
using (var wr = new StreamWriter(stream, utf8NoBom)))
using (var csvWriter = new CsvWriter(wr, CultureInfo.InvariantCulture, false))
{    
    csvWriter.WriteRecords(orders);
}

所有 SFTP 客户端都有(或应该有)使用流上传数据的方法。这意味着您可以使用 Stream.CopyTo 将数据从内存流复制到上传流。假设有OpenWrite,可以修改代码为:

using (var ms = new MemoryStream())
{
    using (var wr = new StreamWriter(stream, Encoding.GetEncoding("ISO-8859-1")))
    using (var csvWriter = new CsvWriter(wr, CultureInfo.InvariantCulture, false))
    {    
        csvWriter.WriteRecords(orders);
    }

    ms.Position=0;

    using(var stream=sftp.OpenWrite(somePath))
    {
        ms.CopyTo(stream);
    }
}

当 CsvHelper 完成时,MemoryStream 的位置在流的末尾并且 CopyTo 不会复制任何内容。通过使用 ms.Position 将位置移动到流的开头。