我为一个用户编写了一个动作,用于下载生成的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在文件末尾添加额外的caracters。 所以在我的例子中,第二个代码解决了我的问题。
但是我也生成了一个我无法读取的Word文档(由于内容存在问题,因此无法打开xxx.docx)。 我想我在这里遇到同样的问题,内存流在文件末尾添加额外的caracters并破坏它。
答案 0 :(得分:11)
问题在于您正在呼叫myStream.GetBuffer()
。 GetBuffer()
方法返回MemoryStream
使用的底层数组,包括不包含实际数据的任何“备用”部分。来自文档:
请注意,缓冲区包含可能未使用的已分配字节。例如,如果将字符串“test”写入MemoryStream对象,则从GetBuffer返回的缓冲区长度为256而不是4,未使用252个字节。要仅获取缓冲区中的数据,请使用ToArray方法;但是,ToArray会在内存中创建数据副本。
不使用GetBuffer()
,而是使用ToArray()
- 或者使用流的长度来了解实际使用的缓冲区数量。
请注意,在您更新的代码中,您基本上将字符串转换为UTF-16 - 这可能意味着它需要的大小是它的两倍,并且它也可能不遵循它声称的编码。我不建议采用这种方法。