Dobry den,

myslim, ze toto je chybny pristup. U streamu byste se vzdy mel rozhodnout,
zda jej obalite jinym streamem nebo jej budete pouzivat primo. Ovsem nikdy
ne chvili tak a chvili onak. A mel byste to udelat co nejdrive (nejlepe
hned pri ziskani streamu). Tj. bud budete mit v doGet

OutputStream out = response.getOutputStream();  // pouzivame "holy" stream

nebo

// stream obalime
OutputStream out = new BufferedOutputStream(response.getOutputStream());

Predani neobaleneho streamu do metody Util.copy() a vytvareni
BufferedOutputStream v teto metode je koncepcne chybne, protoze umoznuje
pristupovat k obalenemu i neobalenemu streamu soucasne.
Navic ServletOutputStream uz je bufferovany, takze obalovat jej dalsim
streamem je asi zbytecne.
[Vlastne jsem to zkousel merit na GlassFishi pomoci JMeteru a skutecne se
zda, ze BufferedOutputStream neprinasi zadnou vyhodu. Nelze to ovsem
povazovat za prukazne, protoze vse (JMeter i GlassFish) bezelo na mem
notebooku.]

Nicmene postup, ktery popisujete, tj. flush() na bufferovany stream a
close() na underlying stream, by mel podle meho nazoru fungovat take. Pro
vznik leaku nevidim duvod.

Z.T.
-- 
Zdenek Tronicek
FIT CTU in Prague


Lukáš Záruba napsal(a):
> Zdravím,
> narazil jsem ve své aplikaci na problém, se streamy a nějak jsem nenašel
> odpověď ani v JavaDocu ani Googlu, tak snad někdo z vás to zrovna řešil :)
> *Situace:*
> Klientský kód (servlet) potřebuje kopírovat nějaký image (prostě data)
> do output streamu. Použije na to mnou vytvořenou util class.
> V této util třídě je metoda, která kopíruje mezi dvěma buffered streamy
> s určitým bufferem atd.
> Metoda copy je ovšem přetížená, aby se v klientském kódu nemusely
> vytvářet buffered streamy, takže existuje i pro klasický Input/Output
> Stream s tím, že je obalí do buffered streamu a zavolá copy metodu pro
> buffered streamy.
> *Problém:*
> Kopírovaní proběhne, nicméně když skončí, ve výstupu není poslední
> buffer, tzn nedošlo k poslednímu "flushi". Je to způsobené tím, že
> klientský kód je odpovědný za zavření streamu (popř. nezavření v
> servletu) a tím dojde k uzavření underlying streamu a ne přímo buffered
> streamu.
> *Triviální řešení:*
> To se dá snadno vyřešit tím, že se v bufferované metodě po kopírování
> provede flush.
> *Otázka:
> *Nevznikají nějaké resource leaky a je vůbec obecně validní zavřít pouze
> underlying stream pod buffered streamem pokud jsem si jistý (ten přidaný
> flush), že jsou do něj zapsána všechna data?
>
> Předem děkuji za všechny reakce.
>
> Lukáš Z.
>
>

Odpovedet emailem