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
将位置移动到流的开头。
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
将位置移动到流的开头。