Many unexpected "nul" characters at the end of xml with MemoryStream

I wrote an action for the user to download the created xml file without having to write it to the server disk, but save it in memory.

Here is my code:

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

Everything looks fine, the XML is correct, I can upload the file, but I don’t understand why I have 691920 "zero" characters at the end of my file (the number of these characters seems to be related to the length of the xml):

enter image description here

Where did they come from? How can I get rid of them?

[Update] I tried this:

 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"); } 

And I did not get the characters "nul". Therefore, I believe that MemoryStream adds extra characters at the end of the file. So in my example with the second code, my problem is solved.

But I also create a Word document that I cannot read (xxx.docx cannot be opened because there are problems with the content). I suppose I have the same problem, the memory stream adds extra characters to the end of the file and corrupts it.

+4
source share
1 answer

The problem is that you are calling myStream.GetBuffer() . The GetBuffer() method returns the base array used by the MemoryStream , including any "spare" parts that do not contain real data. From the documentation:

Note that the buffer contains allocated bytes, which may be unused. For example, if the string "test" is written to a MemoryStream, the length of the buffer returned from GetBuffer is 256, not 4, and 252 bytes are not used. To get only the data in the buffer, use the ToArray method; however, ToArray creates a copy of the data in memory.

Instead of using GetBuffer() use ToArray() - or use the length of the stream to find out how much total buffer is actually being used.

Please note that in the updated code, you basically convert the string to UTF-16, which may well mean that it is twice its size, and it also cannot follow the encoding that it requires. I would not recommend this approach.

+9
source

All Articles