473,382 Members | 1,647 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,382 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 10358
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: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...

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.