I have inlined temporary FileOutputStream that I am not able to explicitly close.

Is that a problem?

File raw = new File(uri.getPath());
Bitmap myBitmap = BitmapFactory.decodeFile(uri.getPath());

File compressedPicture = MEUtils.createTemporaryFile(getPackageName());
// see here
                  new FileOutputStream(compressedPicture));

JpegImageMetadata jpegMetadata = (JpegImageMetadata) Sanselan.getMetadata(raw);
TiffImageMetadata exif = jpegMetadata.getExif();
TiffOutputSet outputSet = exif.getOutputSet();

File compressedPictureWithMetadata = MEUtils.createTemporaryFile(getPackageName());
// see here
OutputStream compressedPictureWithMetadataOutputStream = new BufferedOutputStream(new FileOutputStream(compressedPictureWithMetadata));
new ExifRewriter().updateExifMetadataLossless(compressedPicture,


It seems that BufferedOutputStream can conveniently wrap a FileOutputStream, directly by inline it in the constructor: http://developer.android.com/reference/java/io/BufferedOutputStream.html

  • \$\begingroup\$ in C# I would ask if you have tried a using block. but I don't know enough about Java. does it have something similar? that would automatically close the connection when it is finished using it. \$\endgroup\$ – Malachi Oct 21 '13 at 17:38
  • 1
    \$\begingroup\$ @Malachi There's no Java equivalent, sadly. \$\endgroup\$ – MikeTheLiar Oct 21 '13 at 17:43
  • \$\begingroup\$ I guess you would have to Debug the program and see if the Garbage collection grabs that connection and throws it away. it's never really a good idea to leave a connection open. if the garbage collection grabs it when the application is finished with it you should be fine, but if this is a long running application that will call this code many times before the connection gets closed it will cause issues. I would find a way to close the connection or put it into the ExifRewriter(assuming this is something you wrote) Method \$\endgroup\$ – Malachi Oct 21 '13 at 17:49
  • \$\begingroup\$ @mikeTheLiar In Java 7, there's a try-with-resources block. Too bad it's still not as automatic as C++, where the destructor gets called as soon as a variable goes out of scope. \$\endgroup\$ – 200_success Oct 22 '13 at 9:03

Yes, you do.

While the garbage collector does close your FileOutputStream (by calling finalize), it is not a good idea to rely on it because it runs unpredictably.

This means that if you do not close your streams explicitly, you may run into a limit on the number of simultaneously open files or into inability to open a file until you close the previous stream to it (on Windows) or into unpredictable file content if you open several streams to the same file (on Unix).

  • \$\begingroup\$ The garbage collector only frees the memory occupied bu the object being gc'd. It does not close the file descriptor the OS assigned. \$\endgroup\$ – bowmore Oct 21 '13 at 18:41
  • \$\begingroup\$ @bowmore: It depends on the GC. Are you sure Java's does not? \$\endgroup\$ – sds Oct 21 '13 at 19:49
  • \$\begingroup\$ FileInputStream's finalize() will try to close the file, but the garbage collector itself does not attempt to free any resources other than memory. \$\endgroup\$ – bowmore Oct 21 '13 at 21:09
  • \$\begingroup\$ @bowmore: but the GC will call finalize, right? \$\endgroup\$ – sds Oct 21 '13 at 22:22
  • \$\begingroup\$ Not guaranteed to. From Effective Java (2nd ed;) : 'It is entirely possible, even likely, that a program terminates without executing finalizers on some objects that are no longer reachable. ' \$\endgroup\$ – bowmore Oct 21 '13 at 22:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.