473,397 Members | 2,099 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

Using XmlTextWriter without closing the base stream

I want to write a method that will accept a stream as a parameter, and which
will write xml to the stream (based in reality on database results) using
the XmlTextWriter class. However, this insists on closing my stream, and I
can't convince it not to.

A much-simplified example is below; basically, as soon as the writer is
disposed (marked **** below) the base stream gets closed - which is a pain
if I was still using it ;-p

The base XmlWriter class has a read-only Settings property which in turn has
a CloseOutput property; this would be fine, except Settings is null in the
following, so I can't get to an XmlSettings object to toggle this...

Is there any way to write to such a stream without it getting closed?

Thanks in advance,

Marc
using System;
using System.IO;
using System.Xml;
namespace ConsoleApplication1 {
public static class Program {
public static void Main() {
using (MemoryStream stream = new MemoryStream()) {
WriteXml(stream);
TestStream(stream); // fails - stream now closed on exit of
method
}
}
private static void TestStream(System.IO.Stream stream) {
Console.WriteLine(new string('=', 20));
try {
long position = stream.Position;
stream.Position = 0;
XmlDocument doc = new XmlDocument();
doc.Load(stream);
stream.Position = position;
Console.WriteLine(doc.OuterXml);
} catch (Exception e) {
Console.WriteLine(e); // absorb exception
}
}
public static void WriteXml(Stream stream) {
using (XmlTextWriter writer = new XmlTextWriter(stream, null)) {
writer.Formatting = Formatting.None;
writer.Namespaces = false;
writer.WriteStartElement("Xml");
writer.WriteStartElement("Element");
writer.WriteAttributeString("Attrib1", "Value1");
writer.WriteAttributeString("Attrib2", "Value2");
writer.WriteEndElement();
writer.WriteEndElement();
writer.Flush();
TestStream(writer.BaseStream); // works; stream still open
} // **** closes base stream
}
}
}
Feb 2 '06 #1
8 10368
Might have found it;

XmlWriter.Create

Marc
Feb 2 '06 #2
Thanks for replying; actually, I found that you can do this if you use one
of the overloads to XmlWriter.Create (which accepts the stream and a
settings object).

Marc
Feb 2 '06 #3
If you don't want things disposed then don't dispose of them - remove the
"using" statement from WriteXml.

It is poor design for a method to dispose of a resource that it didn't
acquire [except of course in the case where its job is explicitly defined to
be disposing of the resource].

Also,depending on your design, you should only dispose of either the base
stream or the wrapper - you are effectively trying to do both.

You do not need to explicitly dispose of an XmlTextWriter anywhere unless
you have dispensed with the base stream - garbage collection will handle it
perfectly well.

Finally a MemoryStream is the one type of Stream that does not need to be
disposed AT ALL because it is just managed memory although it is good style
to treat it like any other stream.
"Marc Gravell" <mg******@rm.com> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...
I want to write a method that will accept a stream as a parameter, and
which will write xml to the stream (based in reality on database results)
using the XmlTextWriter class. However, this insists on closing my stream,
and I can't convince it not to.

A much-simplified example is below; basically, as soon as the writer is
disposed (marked **** below) the base stream gets closed - which is a pain
if I was still using it ;-p

The base XmlWriter class has a read-only Settings property which in turn
has a CloseOutput property; this would be fine, except Settings is null in
the following, so I can't get to an XmlSettings object to toggle this...

Is there any way to write to such a stream without it getting closed?

Thanks in advance,

Marc
using System;
using System.IO;
using System.Xml;
namespace ConsoleApplication1 {
public static class Program {
public static void Main() {
using (MemoryStream stream = new MemoryStream()) {
WriteXml(stream);
TestStream(stream); // fails - stream now closed on exit of
method
}
}
private static void TestStream(System.IO.Stream stream) {
Console.WriteLine(new string('=', 20));
try {
long position = stream.Position;
stream.Position = 0;
XmlDocument doc = new XmlDocument();
doc.Load(stream);
stream.Position = position;
Console.WriteLine(doc.OuterXml);
} catch (Exception e) {
Console.WriteLine(e); // absorb exception
}
}
public static void WriteXml(Stream stream) {
using (XmlTextWriter writer = new XmlTextWriter(stream, null))
{
writer.Formatting = Formatting.None;
writer.Namespaces = false;
writer.WriteStartElement("Xml");
writer.WriteStartElement("Element");
writer.WriteAttributeString("Attrib1", "Value1");
writer.WriteAttributeString("Attrib2", "Value2");
writer.WriteEndElement();
writer.WriteEndElement();
writer.Flush();
TestStream(writer.BaseStream); // works; stream still open
} // **** closes base stream
}
}
}

Feb 2 '06 #4
I know what you are saying, and I am glad that I have found a resolution -
however, I'm not quite sure that I agree with all of your points:

Forgetting about streams and writers; if I have an object that is a:
disposable and b: I feel ownership for (in particular if I explicitely
created it), then my instinct tells me that I should dispose of that object.
Due to encapsulation, it isn't necessarily my business to know *exactly*
what is going on under the hood, for instance it could be using a windows
handle, a file, a database resource etc - not my problem.

So:

If I create a class (that happens to be called a stream), should I dispose
it when I am done? I think I should.
If I create a class (that happens to be called a writer, and which uses a
stream), should I still dispose it when I am done? I think I should.
Likewise with the memory stream; technically we know it doesn't need to be,
but that knowledge breaks the black-box rule of encapsulation.

For all I know, the implementation of either the stream or writer
(separately) could involve 17 other disposable / unmanaged objects (in
addition to my stream in the case of the writer), and I would like them to
be cleaned up properly and ASAP; I just don't want it to (necessarily)
dispose of an object that I am still using it just because it knows where it
is.

The main exceptions I can think of to scoped disposal are where I want one
to live longer than its natural scope (i.e. as a return value), but in my
example both entities were tightly scoped in a nested manner. It seems
logical to me to dispose of both of them in turn. Saying "ahh, but its a
stream, so only dispose of it at one level" pollutes things quite a bit to
my mind.

Anyway - I'm happy to disagree, and I'm happy (for this nested usage) to use
a ctor that lets me do this. And I really can see what you are saying about
other uses - I'm just saying that it should be up to me (which, it turns
out, it is). Other examples of more-conveniently handled wrappers are the
compression classes - these take a boolean on an overloaded ctor to let you
tell it "do you want me to close your stream for you?" - and yes, most of
the time you might.

Cheers for the input,

Marc
Feb 2 '06 #5
Marc Gravell wrote:

<snip>
Forgetting about streams and writers; if I have an object that is a:
disposable and b: I feel ownership for (in particular if I explicitely
created it), then my instinct tells me that I should dispose of that object.
Due to encapsulation, it isn't necessarily my business to know *exactly*
what is going on under the hood, for instance it could be using a windows
handle, a file, a database resource etc - not my problem.


<snip>

I entirely agree. I have my own class which might help you with further
such issues:
NonClosingStreamWrapper, which is in my miscellaneous utility library
(although I note I don't mention it on the front page,
unfortunately...)

http://www.pobox.com/~skeet/csharp/miscutil/

Jon

Feb 2 '06 #6
A handy wrapper class; next time I have such an issue (and can't find a
suitable ctor, which is probably the best solution in that it keeps things
simple) I may well make use of this.

Cheers,

Marc
Feb 2 '06 #7

"Marc Gravell" <mg******@rm.com> wrote in message
news:uj**************@TK2MSFTNGP14.phx.gbl...
I know what you are saying, and I am glad that I have found a resolution -
however, I'm not quite sure that I agree with all of your points:

Forgetting about streams and writers; if I have an object that is a:
disposable and b: I feel ownership for (in particular if I explicitely
created it), then my instinct tells me that I should dispose of that
object. Due to encapsulation, it isn't necessarily my business to know
*exactly* what is going on under the hood, for instance it could be using
a windows handle, a file, a database resource etc - not my problem.

So:

If I create a class (that happens to be called a stream), should I dispose
it when I am done? I think I should.
Agreed.
If I create a class (that happens to be called a writer, and which uses a
stream), should I still dispose it when I am done? I think I should.
No - because it uses the stream - it doesn't own it and it doesn't own
anything that needs disposing so it shouldn't be disposed.
Likewise with the memory stream; technically we know it doesn't need to
be, but that knowledge breaks the black-box rule of encapsulation.
That's why I said that good practice would be to dispose of it anyway.
For all I know, the implementation of either the stream or writer
(separately) could involve 17 other disposable / unmanaged objects (in
addition to my stream in the case of the writer), and I would like them to
I think it is quite clear the the writer only implements IDisposable so as
to close the stream.

For the reason that you give it would be very bad practice to have a class
own one resource but just use another.
be cleaned up properly and ASAP; I just don't want it to (necessarily)
dispose of an object that I am still using it just because it knows where
it is.

The main exceptions I can think of to scoped disposal are where I want one
to live longer than its natural scope (i.e. as a return value), but in my
example both entities were tightly scoped in a nested manner. It seems
logical to me to dispose of both of them in turn. Saying "ahh, but its a
stream, so only dispose of it at one level" pollutes things quite a bit to
my mind.
I agree that you can make a case for XmlTextWriter not implementing
IDisposable but I suppose that it is just too useful in the common case
where the stream is a file.
Anyway - I'm happy to disagree, and I'm happy (for this nested usage) to
use a ctor that lets me do this. And I really can see what you are saying
about other uses - I'm just saying that it should be up to me (which, it
turns out, it is). Other examples of more-conveniently handled wrappers
are the compression classes - these take a boolean on an overloaded ctor
to let you tell it "do you want me to close your stream for you?" - and
yes, most of the time you might.


I think that I'd probably agree though that that is the best solution
although a bit ugly. It is just one of the many unfortunate examples of
different practices used in different parts of the framework.
Feb 2 '06 #8
Nick Hounsome <nh***@nickhounsome.me.uk> wrote:
If I create a class (that happens to be called a writer, and which uses a
stream), should I still dispose it when I am done? I think I should.
No - because it uses the stream - it doesn't own it and it doesn't own
anything that needs disposing so it shouldn't be disposed.


How do you know that it (the created instance) doesn't have *other*
things which need to be disposed though?
Likewise with the memory stream; technically we know it doesn't need to
be, but that knowledge breaks the black-box rule of encapsulation.


That's why I said that good practice would be to dispose of it anyway.
For all I know, the implementation of either the stream or writer
(separately) could involve 17 other disposable / unmanaged objects (in
addition to my stream in the case of the writer), and I would like them to


I think it is quite clear the the writer only implements IDisposable so as
to close the stream.


If we're going to go by what's "quite clear" then I don't see that it's
good practice to dispose of a MemoryStream, as it's "quite clear" that
that doesn't have any other resources. Going by intuition is a bad idea
in this kind of thing, IMO.
For the reason that you give it would be very bad practice to have a class
own one resource but just use another.


But that could certainly be the situation in some cases. In those
cases. In those cases, I believe the API should allow you to specify
which resources are effectively owned by the class you're passing them
to, and which resources are owned by the caller.

<snip>
Anyway - I'm happy to disagree, and I'm happy (for this nested usage) to
use a ctor that lets me do this. And I really can see what you are saying
about other uses - I'm just saying that it should be up to me (which, it
turns out, it is). Other examples of more-conveniently handled wrappers
are the compression classes - these take a boolean on an overloaded ctor
to let you tell it "do you want me to close your stream for you?" - and
yes, most of the time you might.


I think that I'd probably agree though that that is the best solution
although a bit ugly. It is just one of the many unfortunate examples of
different practices used in different parts of the framework.


I don't see it as ugly particularly - it's just a matter of telling the
API what it owns and what it doesn't own. In some cases it will be
useful for the new object to own the resource, in some cases not.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 2 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: reddy | last post by:
I am trying to insert a node into an XMLFile. using XMLTextwriter. My Question is Is it possible to do without using XMLDocument. Because its loading all the the file into memory. I just want to...
4
by: Chris | last post by:
Hi, I'm stumped and could use some suggestions. I'm trying to serialize some data to an XML fragment in string form, then deserialize it from a string back to an XML fragment, from which I...
3
by: TS | last post by:
HI, is there any option while using appendChild so that it doesn't do the autotomatic indentation and line breaks so that the tags are appended back to back? thanks
3
by: Magnus | last post by:
can anyone help me on how to create and manipulate a xmttextwriter without having to craete a physical file. I have an application that should return data in xml. But I do not want to create a...
7
by: whatluo | last post by:
Hi, all I'm now working on a program which will convert dec number to hex and oct and bin respectively, I've checked the clc but with no luck, so can anybody give me a hit how to make this done...
1
by: Terrence Chan | last post by:
Does anyone know the size limit of the StringWriter and XmlTextWriter. Dim buffer As New System.IO.StringWriter Dim writer As New System.Xml.XmlTextWriter(buffer) Please point me to some...
2
by: theinsanecoder | last post by:
Hi, i'm using the xmlserializer to load and unload data from my files but i want to crypt them using a not so secure cryptographic encoder. My code to encrypt "seems" to work fine, the file is...
2
by: Random | last post by:
Why, oh why, won't my XmlTextWriter write properly to the MemoryStream. Or, why can't I read the xml back out of the MemoryStream! I can't think of a thing.... Dim reader As XmlReader Dim...
3
by: GaryDean | last post by:
I'm using an XmlTextWriter and it's various methods such as WriteElementString, WriteStartElement, WriteEndElement, etc to create an xml document. When I instantiate the XmlTextWriter to a file......
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.