what is the best way to close a ByteArrayOutputStream?
Asked Answered
E

2

5

I need to optimize a application that uses too much heap memory. I'm having problem in close a ByteArrayOutputStream variable after using the same. I've tried to do using close() but it does not work. this is the code:

ByteArrayOutputStream zipOutTempStream = new ByteArrayOutputStream();
//arquivo.getZipStream() has the XML received by FTP.
//STreamEtils is the function who transfers the XML to zipOutTempStream
StreamUtils.copiarStream(arquivo.getZipStream(), zipOutTempStream);

            //Creating a new XML to write over this.
            File arquivo1 = new File("C:/XML.xml");
            if (arquivo1.exists()) {
                System.out.println("ele existe");
            } else {
                if (arquivo1.createNewFile()) {
                    System.out.println("arquivo criado");
                } else {
                    System.out.println("arquivo não criado");
                }
            }

            FileOutputStream arquivo2 = new FileOutputStream(arquivo1);
            //Copy the unziped XML to the new xml created.
            StreamUtils.copiarStream(StreamUtils                .uncompressXmlFromZipStream(new ByteArrayInputStream(zipOutTempStream.toByteArray())), arquivo2);
            arquivo.setZipStream(null);
            arquivo.setXmlStream(null)      
return arquivo;
Encroach answered 10/4, 2012 at 19:46 Comment(4)
how does it not work? Do you get an error?Souterrain
A ByteArrayOutputStream writes data to a byte array. After closing the ByteArrayOutputStream the byte array is accessible with the toByteArray method. Simply closing the ByteArrayOutputStream will not make the byte array eligible for garbage collection.Vogul
i works, but the problem is that i have a XML of 80MB and after i save in C: , i'd like to free the heap memory used.Encroach
That is the job of the garbage collector. Make sure that you do not have extra references to the ByteArrayOutputStream hanging around.Vogul
V
12

You cannot close a ByteArrayOutputStream, since it's close() method is documented as

Closing a ByteArrayOutputStream has no effect. The methods in this class can be called after the stream has been closed without generating an IOException.

This output stream is backed by an array; it is NOT a buffered stream. If you feel it is using too much memory, you should output bytes directly to some endpoint, such as a file or a socket, using an appropriate OutputStream.

Valentinvalentina answered 10/4, 2012 at 19:51 Comment(1)
the problem is that i should to unzip the file received by FTP and just to get the XML that is in. How can i do that, using what?Encroach
P
3

I think you are carelessly using too much memory. close() has nothing to do with it. In fact there is no need for closing ByteArrayOutputStream. Here you are copying the ZIP file into wrapped byte[] array:

ByteArrayOutputStream zipOutTempStream = new ByteArrayOutputStream();
StreamUtils.copiarStream(arquivo.getZipStream(), zipOutTempStream);

and few lines later you convert the byte[] array back to InputStream:

StreamUtils.copiarStream(StreamUtils.uncompressXmlFromZipStream(
  new ByteArrayInputStream(zipOutTempStream.toByteArray())
), arquivo2);

Seems like this generated byte[] array is pretty huge (confirm with logging). Instead of storing the whole ZIP file in memory (in byte[]) store in a temporary file and read it back.

Pommel answered 10/4, 2012 at 19:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.