4

Я написал действие для пользователя, чтобы загрузить созданный xml, не имея необходимости записывать его на серверный диск, но сохранить его в памяти.Множество неожиданных «nul» символов в конце xml с MemoryStream

Вот мой код:

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 «» caracters последовательности нулевых в конце моего файла (число этих caracters, кажется, связана с длиной XML):

enter image description here

Откуда они пришли? Как я могу избавиться от них?

[Update] Я попытался это:

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

И я не получил "" символы последовательности нулевых. Поэтому я полагаю, что MemoryStream добавляет дополнительные символы в конце файла. Итак, в моем примере с вторым кодом моя проблема решена.

Но я также создаю документ Word, который я не могу прочитать (xxx.docx не может быть открыт, потому что есть проблемы с содержимым). Я полагаю, что у меня такая же проблема, поток памяти добавляет лишние символы в конце файла и повреждает его.

ответ

9

Проблема в том, что вы звоните myStream.GetBuffer(). Метод GetBuffer() возвращает , лежащий в основе массива, используемый MemoryStream, включая любые «запасные» части, которые не содержат реальных данных. Из документации:

Обратите внимание, что буфер содержит выделенные байты, которые могут быть неиспользуемы. Например, если строка «test» записывается в объект MemoryStream, длина буфера, возвращаемого из GetBuffer, равна 256, а не 4, а 252 байта не используется. Чтобы получить только данные в буфере, используйте метод ToArray; однако ToArray создает копию данных в памяти.

Вместо использования GetBuffer() используйте ToArray() - или использовать длину потока, чтобы узнать, сколько из буфера на самом деле использовать.

Обратите внимание, что в обновленном коде вы в основном конвертируете строку в UTF-16, что вполне может означать, что она в два раза больше, чем она должна быть, и она также не может следовать кодировке, которую она требует. Я бы не рекомендовал этот подход.

 Смежные вопросы

  • Нет связанных вопросов^_^