subclass DeflaterOutputStream just to get bytes written?

S

Shea Martin

I am using a deflater output stream, GZIPOutputStream specifically. I
need to know the number of bytes written out by the stream. Obviously
this is not the same number as the number of bytes I have given the
stream. It looks like the only way to get this information is through
the 'def' field, calling getBytesWritten(), or getTotalOut(), depending
on whether I want a long or an int. The problem is that the 'def' field
is protected. So to get this information, I have to subclass
GZIPOutputstream.

Surely, it is fairly common to need this information. Is this a design
flaw, or am I just too stupid to see an easier way to get this information?

Thanks,

~Shea M.
 
J

jan V

Surely, it is fairly common to need this information. Is this a design

Common on, give those Sun engineers a bit of credit. It's not because a
class doesn't expose every possible usage scenario that we're allowed to
call this a "design flaw". The OP can achieve his goal by subclassing, so I
think there's absolutely no flaw whatsoever - just an inconvenience. Sun is
pretty good at making a lot of things less than convenient.. but flaws are
very different beasts.
 
S

Shea Martin

jan said:
Surely, it is fairly common to need this information. Is this a design
flaw, [...]

Yup.


Common on, give those Sun engineers a bit of credit. It's not because a
class doesn't expose every possible usage scenario that we're allowed to
call this a "design flaw". The OP can achieve his goal by subclassing, so I
think there's absolutely no flaw whatsoever - just an inconvenience. Sun is
pretty good at making a lot of things less than convenient.. but flaws are
very different beasts.

Point taken, but this isn't some obscure situation. I would hazzard to
guess that at least half* the people who use the class would want to
know such information.

~S
 
C

Chris Head

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Shea said:
I am using a deflater output stream, GZIPOutputStream specifically. I
need to know the number of bytes written out by the stream. Obviously
this is not the same number as the number of bytes I have given the
stream. It looks like the only way to get this information is through
the 'def' field, calling getBytesWritten(), or getTotalOut(), depending
on whether I want a long or an int. The problem is that the 'def' field
is protected. So to get this information, I have to subclass
GZIPOutputstream.

Surely, it is fairly common to need this information. Is this a design
flaw, or am I just too stupid to see an easier way to get this information?

Thanks,

~Shea M.

Hi,
Wouldn't it be easier and more appropriate to write a filter stream for
this purpose? Make a class called ByteCounterOutputStream. Instead of
wrapping GZIPOutputStream directly around FileOutputStream, put the
ByteCounterOutputStream between them. ByteCounterOutputStream simply
passes bytes written to it to the underlying stream, but also counts how
many bytes pass through it.

Chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (MingW32)

iD8DBQFDA9Ma6ZGQ8LKA8nwRAmIGAJwM0Vf11UscWR/yk+kzakHXkb2YXgCgjEkF
4t27xvarlPHg08d8W4xgZ+0=
=RU56
-----END PGP SIGNATURE-----
 
C

Chris Uppal

jan said:
Surely, it is fairly common to need this information. Is this a design
flaw, [...]

Yup.

Common on, give those Sun engineers a bit of credit.

What !? Why on earth would I want to do that ??

;-)

It's not because a
class doesn't expose every possible usage scenario that we're allowed to
call this a "design flaw".

Actually, I would go further and call it (in its small way) an example of
bloody awful design.

There are four integer values that the internal compressor had to maintain, and
which are potentially useful outside the implementation itself (because they
are used in various protocols / file formats that use zlib-style compression).
They are the compressed size, the uncompressed size, the "Adler" checksum, and
a different CRC checksum. The first two of those can usually be found by other
means, but the last two are not sensibly accessible from anything except the
compressor. Note that this is true whether the compressor is implemented using
the zlib library (as I believe it is now) or by pure Java code, or my some
other mechanism. Now, /given/ that there is a need to get at the last two of
those numbers, it seems reasonable to use the same technique to provide access
to the first two. And, in fact, that's what the Sun code does. Fair enough so
far.

But what's /really/ stupid is the decision to expose those numbers as protected
int fields. In the first place, by making them protected, they (effectively)
make them completely public. That has the (relatively minor) consequence that
"anyone" can change them. More importantly they become part of the public
contract of that class -- any future implementation has to contain them, and
has to maintain their meaning. Making them "protected" gains /nothing/ in
terms of encapsulation over making them fully public. Secondly, why make them
fields at all ? As it happens the compressor maintains those values anyway, so
there's nothing much to gain by copying them into the stream object (though it
may be worthwhile nevertheless). Providing access via an getter method (and
thus hiding the implementation detail of /where/ the values were stored) would
be an obvious improvement. And that would also prevent anyone changing the
values -- which there is no reason for anyone ever to want to do.

So, I say that there are two separate design errors here. The choice of
protected access, and the decision to expose the data as fields, rather than
via a method. They make the class harder to use (since you have to mess around
with subclassing). They reduce encapsulation. They provide /nothing/ in
exchange.

Bad design.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top