5

我为用户编写了一个操作来下载生成的 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):

在此处输入图像描述

他们是从哪里来的?我怎样才能摆脱它们?

[更新] 我试过这个:

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 在文件末尾添加了额外的字符。因此,在我的示例中,第二个代码解决了我的问题。

但我也生成了一个我无法阅读的 Word 文档(xxx.docx 无法打开,因为内容有问题)。我想我在这里有同样的问题,内存流在文件末尾添加了额外的字符并损坏了它。

4

1 回答 1

11

问题是您正在调用myStream.GetBuffer(). 该GetBuffer()方法返回由 使用的底层数组MemoryStream,包括任何不包含真实数据的“备用”部分。从文档中:

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

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

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

于 2013-04-18T14:53:13.987 回答