On Thu, Jul 05, 2001 at 03:04:59PM +1000, Peter Donald wrote:
> On Thu, 5 Jul 2001 10:41, jeff wrote:
> > In a dark corner of Excalibur lies a rather unexciting class called
> > IOUtils.java. It lets you copy between InputStreams and OutputStreams,
> > cleanly shut down streams, and that's it.
> >
> > Over the last week I have ruthlessly expanded it's functionality, such
> > that there are now methods to copy from (InputStream|Reader|String) to
> > (OutputStream|Writer|String), with variants to select the buffer size
> > and (where appropriate) the byte->char encoding.
>
> kewl ;)
>
> > Example uses:
> >
> > // Read text from a file to a String
> > String s = IOUtil.toString( new FileReader("foo.txt") );
> >
> > // Copy the jakarta home page to a File:
> > IOUtil.copy(
> > new URL("http://jakarta.apache.org").openStream(),
> > new FileOutputStream("index.html")
> > ).close();
>
> excellent. The only one thing I don't like is return the OutputStream/Writer
> at the end. I like the following approach better
>
> final InputStream input = new URL("http://jakarta.apache.org").openStream();
> final FileOutputStream output = new FileOutputStream("index.html");
> try { IOUtil.copy( input, output ); }
> finally
> {
> IOUtil.shutdownStream( input );
> IOUtil.shutdownStream( output );
> }
>
> because it forces users to deal with exceptions.
That approach works perfectly well whether or not the copy() method
returns it's second arg. Likewise, if the copy() methods didn't return
anything, it would be just as easy to write "bad" code. Returning the
second arg simply gives users the option.
> Otherwise you get cases like
>
> IOUtil.copy(
> new URL("http://jakarta.apache.org").openStream(),
> new FileOutputStream("index.html")
> ).close()
>
> When this raises an exception the output stream is never shutdown and you can
> quickly foobar the system. I actually had a security leak caused by this once
> (my authenticator would stop authenticating after ~256 requests as it would
> hit FD limit for process). SO it is possible I am just particularly sensitive
> on this issue ;)
Why was your app throwing 256+ IOExceptions during normal operation
anyway? ;) Looking at FileOutputStream.finalize(), it does close() the
stream, so all you needed to do was gc() occasionally.
So to summarise, first I don't see how limiting the user's choice
encourages "better" use, and second I don't see why it is desirable to
close() all streams manually in exceptional circumstances, when the gc
could do it.
Of course, I'm just whinging 'cause I don't want to rewrite stuff ;) If
you can clarify the above I'l happily fix the code.
> Thoughts?
Interested to hear other people's too.
> BTW instead of diffing against /dev/null it would be better to just send file
> so CVS weenies like myself don't end up scratching their heads ;)
Try 'cvs patch -p0 < IOUtil-patches.diff' from the project root. Btw, should
patches be from the project root? How about multi-file patches?
--Jeff
>
> Cheers,
>
> Pete
>
> *-----------------------------------------------------*
> | "Faced with the choice between changing one's mind, |
> | and proving that there is no need to do so - almost |
> | everyone gets busy on the proof." |
> | - John Kenneth Galbraith |
> *-----------------------------------------------------*
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]