在带有MemoryStream的xml末尾有很多意想不到的“nul”字符

时间:2013-04-18 14:48:55

标签: c# asp.net-mvc linq-to-xml memorystream filecontentresult

我为一个用户编写了一个动作,用于下载生成的xml,而不必将其写在服务器磁盘上,但将其保存在内存中。

这是我的代码:

public FileContentResult MyAction()
{
  MemoryStream myStream = new MemoryStream();
  XDocument xml = GenerateXml(...);
  xml.Save(myStream );
  myStream .Position = 0;
  return File(myStream.GetBuffer(), "text/xml", "myFile.xml");
}

一切似乎工作正常,XML是正确的,我可以下载文件,但我不明白为什么我的文件末尾有691920个“nul”字符(这些字符的数量似乎是相关的到xml的长度:

enter image description here

他们来自哪里?我怎么能摆脱他们?

[更新] 我试过这个:

public FileContentResult MyAction()
{
  XDocument xml = GenerateXml(...);
  byte[] bytes = new byte[xml.ToString().Length * sizeof(char)];
  Buffer.BlockCopy(xml.ToString().ToCharArray(), 0, bytes, 0, bytes.Length);
  return File(bytes, "text/xml", "myFile.xml");
}

我没有得到“nul”字符。所以我想这是MemoryStream在文件末尾添加额外的caracters。 所以在我的例子中,第二个代码解决了我的问题。

但是我也生成了一个我无法读取的Word文档(由于内容存在问题,因此无法打开xxx.docx)。 我想我在这里遇到同样的问题,内存流在文件末尾添加额外的caracters并破坏它。

1 个答案:

答案 0 :(得分:11)

问题在于您正在呼叫myStream.GetBuffer()GetBuffer()方法返回MemoryStream使用的底层数组,包括不包含实际数据的任何“备用”部分。来自文档:

  

请注意,缓冲区包含可能未使用的已分配字节。例如,如果将字符串“test”写入MemoryStream对象,则从GetBuffer返回的缓冲区长度为256而不是4,未使用252个字节。要仅获取缓冲区中的数据,请使用ToArray方法;但是,ToArray会在内存中创建数据副本。

不使用GetBuffer(),而是使用ToArray() - 或者使用流的长度来了解实际使用的缓冲区数量。

请注意,在您更新的代码中,您基本上将字符串转换为UTF-16 - 这可能意味着它需要的大小是它的两倍,并且它也可能不遵循它声称的编码。我不建议采用这种方法。