When I close a BufferedInputStream, is the underlying InputStream also closed? [duplicate] - java

This question already has answers here:
Closing inputstreams in Java
(6 answers)
Closed 3 years ago.
InputStream in = SomeClass.getInputStream(...);
BufferedInputStream bis = new BufferedInputStream(in);
try {
// read data from bis
} finally {
bis.close();
in.close();
}
The javadoc for BufferedInputStream.close() doesn't mention whether or not the underlying stream is closed:
Closes this input stream and releases any system resources associated
with the stream. Once the stream has been closed, further read(),
available(), reset(), or skip() invocations will throw an IOException.
Closing a previously closed stream has no effect.
Is the explicit call to in.close() necessary, or should it be closed by the call to bis.close()?

From the source code of BufferedInputStream :
public void close() throws IOException {
byte[] buffer;
while ( (buffer = buf) != null) {
if (bufUpdater.compareAndSet(this, buffer, null)) {
InputStream input = in;
in = null;
if (input != null)
input.close();
return;
}
// Else retry in case a new buf was CASed in fill()
}
}
So the answer would be : YES

BufferedInputStream doesn't hold any system resources itself; it simply wraps around an InputStream which holds those resources. Therefore the BufferedInputStream forwards the close operation onto the wrapped InputStream which will then release its resources.

When you close a BufferedInputStream, the underlying InputStream is indeed also closed. :)

Yes. The underlying stream will be closed.

Here is the Java implementation
/**
* Closes this input stream and releases any system resources
* associated with the stream.
* Once the stream has been closed, further read(), available(), reset(),
* or skip() invocations will throw an IOException.
* Closing a previously closed stream has no effect.
*
* #exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
byte[] buffer;
while ( (buffer = buf) != null) {
if (bufUpdater.compareAndSet(this, buffer, null)) {
InputStream input = in;
in = null;
if (input != null)
input.close();
return;
}
// Else retry in case a new buf was CASed in fill()
}
}
So, the stream will be closed

Related

finally { if (inputStream != null) { inputStream.close();

I don't know how to understand this:
{
if (inputStream **!= null**) {
inputStream.close();
from that example:
public class CopyLines {
public static void main(String[] args) throws IOException {
BufferedReader inputStream = null;
PrintWriter outputStream = null;
try {
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
String l;
while ((l = inputStream.readLine()) != null) {
outputStream.println(l);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}}
inputStream is beeing closed when there is any data provided???
It means that whenever the try block is completed (successfully or not) it will try to close the streams (inputStream and outputStream) in the finally block but as the try block could fail while creating the instance of BufferedReader or PrintWriter, you need to check first if it is not null otherwise you will get a NPE.
You can consider using try-with-resouces statement to avoid having to check if null and calling close() explicitly such that it would simplify your code a lot.
try (BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt")) {
// your code here
}
If you're asking why this code is in finally block, then,
This is simply to ensure that the inputStream and outputStream will always be closed, no matter whether the code above encounters or doesn't encounters an exception.
How is it different.
The difference is during any exception. If any exception occurs, then instead of simply returning, it will ensure that both the streams are closed before returning the exception to the method that called this method.
bacause java's finally block is always executed, unless:
System.exit is called
or JVM crashes
This is a common practice to close stream, database, or any other similar connections in finally blocks. This ensures that the connections are always closed. Because if they aren't in finally block, and system is continuously encountering some or the other Excpetion then it will eventually run out of connections.
That's just to avoid null pointer exception. The functions are called only when object is not null.
In simple words, close function is only called when the objects are not null else if you call close() on object with null value, you will come across null pointer exception.
Interesting thing is the usage of finally, which is always called whether there is any exception or not.
When the execution reaches the finally block, it is first checked inputstream and outputstream are null or not then both the streams are closed to free the resources.
Please refer the link to check about try with finally : https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2

Java EOFException While Reading Object From A Server (not a file) [duplicate]

This question already has an answer here:
Why is ObjectInputStream readObject() throwing EOF exception
(1 answer)
Closed 7 years ago.
So, I write an object to a client like so:
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
out.writeObject(args);
out.close();
And receive the object on the client side like so:
ObjectInputStream in = new ObjectInputStream(connection.getInputStream());
Object objIn;
while(true) {
if((objIn = in.readObject()) != null) {
//work with obj
}
}
I never create an output stream on the client side or an input stream on the server side.
Also, the object I send is serializable.
Thanks for you help!
EDIT: The "duplicate" of this question doesn't help me answer my problem, so this one is not a duplicate.
while(true) {
if((objIn = in.readObject()) != null) {
//work with obj
}
}
Q. Why are you testing for null? Are you planning on sending a null? Because that's the only time you'll ever get one.
A. Because you think readObject() returns null at end of stream. Although you've left out the break that would escape the infinite loop.
It doesn't. It throws EOFException. So your loop should look like this:
try
{
while(true) {
objIn = in.readObject();
//work with obj
}
}
catch (EOFException exc)
{
// end of stream
}
finally
{
in.close();
}
Assuming you received the exception while reading the input stream from connection Object .
If you already invoked the connection.getInputStream() prior to the above cited code for input stream you will receive a EOF exception . Because the input Stream in the connection object is already consumed .
related topic
One solution to such problem is to write the content of the input stream in a Random access file as they enables you to traverse through the file .
public static RandomAccessFile toRandomAccessFile(InputStream is, File tempFile) throws IOException
{
RandomAccessFile raf = new RandomAccessFile(tempFile, "rwd");
byte[] buffer = new byte[2048];
int tmp = 0;
while ((tmp = is.read(buffer)) != -1)
{
raf.write(buffer, 0, tmp);
}
raf.seek(0);
return raf;
}
Later you can always read from the file as follows .
public static InputStream toInputStream(RandomAccessFile file) throws IOException
{
file.seek(0); /// read from the start of the file
InputStream inputStream = Channels.newInputStream(file.getChannel());
return inputStream;
}

try-with behavior with implicit and explicit closeables

Are the following try-with blocks similar? Will the dataSocket.getOutputStream() be closed in both cases?
a)
try (Socket dataSocket = new Socket(...);
OutputStream socketStream = dataSocket.getOutputStream();
BufferedOutputStream outputStream = new BufferedOutputStream(socketStream)
) {.....}
b)
try (Socket dataSocket = new Socket(...);
BufferedOutputStream outputStream = new BufferedOutputStream(dataSocket.getOutputStream())
) {.....}
Note. in b) there is no explicit variable for dataSocket.getOutputStream(), in a) we have socketStream.
According to BufferedOutputStream JavaDoc,
Closes this output stream and releases any system resources associated with the stream.
Closing outputStream would close the underlying outputstream. This is also proven in the source code of BufferedOutputStream's close() method.
public void close() throws IOException {
try {
flush();
} catch (IOException ignored) {
}
out.close();
}
Yes, it will be closed in both cases. Even using only Socket sentence, they should be closed. When socket is closed, streams are closed. Anyway, I prefer explicity add Streams declaration on try-with structure.

Java IOException while trying to copy inputstream to outputstream

I'am trying to write the inputstream image to OutputStream to display the image in the browser this is the code:
try
{
InputStream input = Filer.readImage("images/test.jpg");
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1)
{
responseBody.write(buffer, 0, bytesRead);
}
}
catch(IOException e)
{
System.out.println(e);
}
the readImage:
public static InputStream readImage(String file) throws IOException {
try (InputStream input = new FileInputStream(file)) {
return input;
}
}
but I get an error while writing:
java.io.IOException: Stream Closed
any ideas?
The try-with-resources closes the stream when you exit the block
try (InputStream input = new FileInputStream(file)) {
ie. when your method returns.
Just remove it and take care of closing the stream at the end of your other method body.
As stated in the comments, here's a link to the official tutorial on try-with-resources.
Taken from oracle tutorial the resource is closed when the statement completes:
The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. The following example uses a finally block instead of a try-with-resources statement:

Sonar violation: "Method may fail to close stream on exception"

I have this method:
private void unZipElementsTo(String inputZipFileName, String destPath) throws FileNotFoundException, IOException {
OutputStream out = null;
InputStream in = null;
ZipFile zf = null;
try {
zf = new ZipFile(inputZipFileName);
for (Enumeration<? extends ZipEntry> em = zf.entries(); em.hasMoreElements();) {
ZipEntry entry = em.nextElement();
String targetFile = destPath + FILE_SEPARATOR + entry.toString().replace("/", FILE_SEPARATOR);
File temp = new File(targetFile);
if (!temp.getParentFile().exists()) {
temp.getParentFile().mkdirs();
}
in = zf.getInputStream(entry);
out = new FileOutputStream(targetFile);
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.flush();
out.close();
in.close();
}
}
finally
{
if (out!=null) out.close();
if (zf!=null) zf.close();
if (in!=null) in.close();
}
}
For this method Sonar give me this Violation:
Bad practice - Method may fail to close stream on exception
unZipElementsTo(String, String) may fail to close stream on exception
But, I don't see any violations there. Maybe, it is just a False-positive ?
That's right.
The OutputStream.close() method can itself throw an exception.
If this happens, e.g. on the 1st line of your finally{} block, then the other streams will be left open.
If out.close() or zf.close() in the finally block throw an exception then the other closes won't be executed.
Alternatively if you're using Java 7 or better, you can use the new try-with-resources mechanism, which handles the close for you. See: http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html for details on this new mechanism.
Note that try-with-resources also works with multiple objects that are opened and closed and still preserves the guarantee that objects will be closed in the reverse order of their construction. Quoth that same page:
Note that the close methods of resources are called in the opposite order of their creation.
To avoid masking an exception with an exception during the close of the streams
It's often recommended to "hide" any io exception in the finally.
To fix use the org.apache.commons.io.IOUtils.closeQuietly(...)
or guava Closeables.html#closeQuietly(java.io.Closeable)
in the finally close
more on exception handling issues :
http://mestachs.wordpress.com/2012/10/10/through-the-eyes-of-sonar-exception-handling/

Categories