Почему при использовании StreamWriter для записи текста в строку ничего не пишется? - PullRequest
1 голос
/ 19 января 2012

У меня есть следующий код

    public void SerializeToStream(Stream stream)
    {
        var xml = // Linq to xml code here

        // Write to the stream
        var writer = new StreamWriter(stream);
        writer.Write(xml.ToString());
    }

Мой xml объект имеет правильные данные, и я убедился, что xml.ToString() показывает все правильно, но после writer.Write(xml.ToString()) вызывается мой входящий поток (независимо от того, является ли он FileStream или MemoryStream по-прежнему ничего в нем (и длиной ноль). Никаких исключений не выдается. Почему это происходит?

Как примечание, я не могу использовать xml.WriteTo(), потому что класс XmlWriter добавляет дополнительные вещи (тег объявления <xml>), которых я не могу иметь в своем xml (Политика компании для интеграции с другой системой, которой я не могу управлять более).

Ответы [ 3 ]

7 голосов
/ 19 января 2012

Вы никогда не смываете и не закрываете писателя.(Я бы обычно предлагал закрыть программу записи, но это также закроет поток, что может быть не тем, что вы хотите.) Просто добавьте:

writer.Flush();

в конце метода.

Обратите внимание, что вы можете удалить объявление XML из XDocument, если хотите.Например:

XDocument doc = new XDocument
    (new XDeclaration("1.0", "utf-8", "yes"),
     new XElement("Root", "content"));
doc.Save(Console.Out); // Includes <? xml ... ?>
doc.Declaration = null;
doc.Save(Console.Out); // No declaration...

Это должно упростить задачу:

public void SerializeToStream(Stream stream)
{
    var xml = // Linq to xml code here
    xml.Declaration = null;
    xml.Save(stream);
}
2 голосов
/ 19 января 2012

Держу пари, что это потому, что вы не закрываете StreamWriter; промывка, скорее всего, тоже подойдет.

Оборачивая его в блок использования, вы позаботитесь об обоих.

...
    using (var writer = new StreamWriter(stream))
    {
        writer.Write(xml.ToString());
    }
...

Примечание (от @Tigran): using: это также повлияет на объект потока, что может быть не очень хорошим выбором в функции, которая принимает поток как параметр.

1 голос
/ 19 января 2012

Как правило, каждый раз, когда вы используете класс, который реализует интерфейс IDisposable, вам действительно следует заключить его в блок using. Это гарантирует, что метод .Close () вызывается до того, как объект выходит из области видимости, освобождая ресурсы. Я также заметил, что без .Flush () в конце содержимое не всегда записывается.

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

using (var writer = new StreamWriter(stream))
{
    writer.Write(xml.ToString());
    writer.Flush();
    // writer.Close() can be called here, but is automatically called at the end of the using block
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...