C# Streamwriter - 编码问题
C# Streamwriter - Problem with the encoding
我有一些产品数据要写入 csv 文件。首先,我有一个将 header 写入 csv 文件的函数:
using(StreamWriter streamWriter = new StreamWriter(path))
{
string[] headerContent = {"banana","apple","orange"};
string header = string.Join(",", headerContent);
streamWriter.WriteLine(header);
}
另一个函数遍历产品并将其数据写入 csv 文件:
using (StreamWriter streamWriter = new StreamWriter(new FileStream(path, FileMode.Open), Encoding.UTF8))
{
foreach (var product in products)
{
await streamWriter.WriteLineAsync(product.ToString());
}
}
使用 FileMode.Open
和 Encoding.UTF8
将产品写入 csv 文件时,文件中的编码设置正确,这意味着德语或法语中的特殊字符可以正确显示。但这里的问题是,当我这样做时,我会覆盖我的 header。
我尝试的解决方案是不使用 FileMode.Open
而是使用 FileMode.Append
这有效,但由于某种原因编码被忽略了。
如何在保持编码的同时追加数据?还有为什么会发生这种情况?
编辑:
示例FileMode.Open
:
Fußpflegecreme
示例FileMode.Append
:
Fu_pflegecreme
我想只要你在编写 header 时明确选择 utf8 编码就可以解决这个问题。这将为文件添加 BOM 前缀。
这里的重要问题是:文件实际包含什么;例如,如果我使用以下内容:
using System.Text;
string path = "my.txt";
using (StreamWriter streamWriter = new StreamWriter(new FileStream(path, FileMode.Create), Encoding.UTF8))
{
streamWriter.WriteLine("Fußpflegecreme 1");
}
using (StreamWriter streamWriter = new StreamWriter(new FileStream(path, FileMode.Append), Encoding.UTF8))
{
streamWriter.WriteLine("Fußpflegecreme 2");
}
// this next line is lazy and inefficient; only good for quick tests
Console.WriteLine(BitConverter.ToString(File.ReadAllBytes(path)));
那么输出是(re-formatted一点):
EF-BB-BF-
46-75-C3-9F-70-66-6C-65-67-65-63-72-65-6D-65-20-31-0D-0A-
46-75-C3-9F-70-66-6C-65-67-65-63-72-65-6D-65-20-32-0D-0A
第一行(注意:原始十六进制中没有任何“行”)是 UTF-8 BOM;第二行和第三行是正确的 UTF-8 编码的有效载荷。如果您可以显示在您的案例中写入的确切字节,将会有所帮助。我想知道这里真正的问题是不是在你的版本中,没有BOM,但其余数据都是正确的。有些工具在没有 BOM 的情况下会选择错误的编码。而且,一些工具:存在 BOM: 会在文件开头错误地显示一些垃圾(而且也可能,因为它们显然没有使用 BOM:使用错误的编码)。首选选项是:在 读取 文件时明确指定编码,并使用可以处理 BOM 存在与否的工具。
是否包含 BOM(尤其是在 UTF-8 的情况下)是一个复杂的问题,每个问题都有 pros/cons - 并且有些工具可以更好地工作,或者更糟,每个。许多 UTF-8 文本文件 不 包含 BOM,但是:没有通用的答案。无论是否有 BOM,实际内容仍然是正确的 UTF-8 编码 - 但如何解释(在任何一种情况下)取决于您用来读取数据的特定工具(以及该工具的配置方式).
我有一些产品数据要写入 csv 文件。首先,我有一个将 header 写入 csv 文件的函数:
using(StreamWriter streamWriter = new StreamWriter(path))
{
string[] headerContent = {"banana","apple","orange"};
string header = string.Join(",", headerContent);
streamWriter.WriteLine(header);
}
另一个函数遍历产品并将其数据写入 csv 文件:
using (StreamWriter streamWriter = new StreamWriter(new FileStream(path, FileMode.Open), Encoding.UTF8))
{
foreach (var product in products)
{
await streamWriter.WriteLineAsync(product.ToString());
}
}
使用 FileMode.Open
和 Encoding.UTF8
将产品写入 csv 文件时,文件中的编码设置正确,这意味着德语或法语中的特殊字符可以正确显示。但这里的问题是,当我这样做时,我会覆盖我的 header。
我尝试的解决方案是不使用 FileMode.Open
而是使用 FileMode.Append
这有效,但由于某种原因编码被忽略了。
如何在保持编码的同时追加数据?还有为什么会发生这种情况?
编辑:
示例FileMode.Open
:
Fußpflegecreme
示例FileMode.Append
:
Fu_pflegecreme
我想只要你在编写 header 时明确选择 utf8 编码就可以解决这个问题。这将为文件添加 BOM 前缀。
这里的重要问题是:文件实际包含什么;例如,如果我使用以下内容:
using System.Text;
string path = "my.txt";
using (StreamWriter streamWriter = new StreamWriter(new FileStream(path, FileMode.Create), Encoding.UTF8))
{
streamWriter.WriteLine("Fußpflegecreme 1");
}
using (StreamWriter streamWriter = new StreamWriter(new FileStream(path, FileMode.Append), Encoding.UTF8))
{
streamWriter.WriteLine("Fußpflegecreme 2");
}
// this next line is lazy and inefficient; only good for quick tests
Console.WriteLine(BitConverter.ToString(File.ReadAllBytes(path)));
那么输出是(re-formatted一点):
EF-BB-BF-
46-75-C3-9F-70-66-6C-65-67-65-63-72-65-6D-65-20-31-0D-0A-
46-75-C3-9F-70-66-6C-65-67-65-63-72-65-6D-65-20-32-0D-0A
第一行(注意:原始十六进制中没有任何“行”)是 UTF-8 BOM;第二行和第三行是正确的 UTF-8 编码的有效载荷。如果您可以显示在您的案例中写入的确切字节,将会有所帮助。我想知道这里真正的问题是不是在你的版本中,没有BOM,但其余数据都是正确的。有些工具在没有 BOM 的情况下会选择错误的编码。而且,一些工具:存在 BOM: 会在文件开头错误地显示一些垃圾(而且也可能,因为它们显然没有使用 BOM:使用错误的编码)。首选选项是:在 读取 文件时明确指定编码,并使用可以处理 BOM 存在与否的工具。
是否包含 BOM(尤其是在 UTF-8 的情况下)是一个复杂的问题,每个问题都有 pros/cons - 并且有些工具可以更好地工作,或者更糟,每个。许多 UTF-8 文本文件 不 包含 BOM,但是:没有通用的答案。无论是否有 BOM,实际内容仍然是正确的 UTF-8 编码 - 但如何解释(在任何一种情况下)取决于您用来读取数据的特定工具(以及该工具的配置方式).