【问题标题】:Writing a string to MemoryStream corrupts the input将字符串写入 MemoryStream 会破坏输入
【发布时间】:2015-06-03 21:01:14
【问题描述】:

我有一个 ASP.net 项目,并且希望在发送 AJAX 帖子时返回一个 CSV 文件(是的,它有效。请参阅 Handle file download from AJAX post)。 特殊的是,我想在 MemoryStream 中创建结果以将其作为 FileResult 返回。 但我现在的问题是,德语变音符号(ä、ö、ü)被破坏了。所以这是我的代码:

public ActionResult Download(FormCollection form) {
string[] v = new string[16];
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream, 
    System.Text.Encoding.GetEncoding("Windows-1252"));
SqlCommand cmd = dbconn.CreateCommand();
//create SQL command
while (rs.Read()) {
  v = new string[16];
  v[0] = rs.GetString("IstAktiv");
  v[1] = rs.GetString("Haus");
  //cache all the values
  ...
  //write cached values
  for (int i = 0; i < v.Length; i++) {
    if (i > 0) writer.Write(";");
    writer.Write(v[i]);
    writer.Flush();
  }
  writer.Write("\r\n");
  writer.Flush();
} //end while rs.Read()

FileContentResult ret = new FileContentResult(stream.ToArray(), "text/csv");
ret.FileDownloadName = "Kontakte.csv";
writer.Close();
return ret;
} //end method

所以当我在 Excel 中打开生成的文件时,变音符号会被转换成奇怪的东西。例如,大写字母“Ä”更改为“�”。 那么有没有办法解决这个问题呢?

最好的问候

【问题讨论】:

  • 你试过不同的编码吗?
  • //System.Text.Encoding.GetEncoding("UTF-8") //*/ //System.Text.Encoding.GetEncoding(1141) //*/ //System.Text.Encoding.Unicode //System.Text.Encoding.GetEncoding("Windows-1250") 是的,这些是其他编码,我试过了。我用 UTF-8 得到了最好的结果。在普通记事本中打开文件时一切都很好,但是当我在 Excel 中打开同一个文件时,变音符号无论如何都已损坏。所以我将文件保存在记事本中作为 ANSI 编码的文件,甚至 Excel 也可以显示它们应该显示的变音符号
  • 你可以试试 System.Text.Encoding.GetEncoding(850) 吗?
  • 这不是损坏,而是编码错误。您不是使用 Unicode,而是强制转换为 Windows 1252。改用 Unicode
  • @GeorgeChond 问题是 OP 正在 尝试更改编码,导致转换错误。 .NET 用户 Unicode,没有理由尝试不同的编码

标签: c# asp.net-mvc


【解决方案1】:

要让 Excel 正确读取 CSV 文件,它要求 CSV 文件采用 UTF-8 编码(带有 BOM)。

因此,毫无疑问,您的 StreamWriter 必须这样设置:

StreamWriter writer = new StreamWriter(stream, 
    System.Text.Encoding.GetEncoding("UTF-8"));

但是,如果这对您不起作用,那么很可能是因为字符在您甚至有机会将它们写入流之前就已损坏。当您从数据库中读取数据时,您可能会遇到编码转换问题。

v = new string[16];
v[0] = rs.GetString("IstAktiv");
v[1] = rs.GetString("Haus");

要验证这一点,请在将值读入“v”数组时放置一个断点,并检查在此步骤中字符是否仍然正常。如果它们已损坏,那么您就知道问题出在代码和数据库之间,而写入 CSV 不是问题。

编辑:这是一个孤立的测试用例,您可以使用它来证明 UTF-8 是编写 CSV 的正确编码。也许您可以先尝试一下:

 Encoding enc = Encoding.GetEncoding("UTF-8");
 using (StreamWriter writer = new StreamWriter(@"d:\test\test.csv", false, enc))
 {
    writer.Write(@"""hello ä, ö, ü world""");
 }

【讨论】:

  • 我设置了断点,写入值数组v的数据是正确的。
  • 您不需要创建新的 UTF8 编码,它可以作为静态属性使用,Encoding.UTF8
  • @Mecki Matschbirne:我建议您自己编写一个独立的测试用例,在其中直接将值写入流,而不从数据库中读取。这就是我刚才所做的,使用你提到的字符。我让它们在 Excel 中正确打开的唯一方法是确保 CSV 为 UTF-8 格式(带有 BOM)。您可以尝试一下并告诉我们您得到了什么结果吗?
  • @Panagiotis Kanavos:正确。你也可以那样做。 +1
  • 您确定 Excel 使用 UTF-8 吗?这不是我的经验。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 2022-12-17
  • 2017-09-02
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
相关资源
最近更新 更多