In this java code,
import java.io.IOException;
public class Copy
{
public static void main(String[] args)
{
if (args.length != 2)
{
System.err.println("usage: java Copy srcFile dstFile");
return;
}
int fileHandleSrc = 0;
int fileHandleDst = 1;
try
{
fileHandleSrc = open(args[0]);
fileHandleDst = create(args[1]);
copy(fileHandleSrc, fileHandleDst);
}
catch (IOException ioe)
{
System.err.println("I/O error: " + ioe.getMessage());
return;
}
finally
{
close(fileHandleSrc);
close(fileHandleDst);
}
}
static int open(String filename)
{
return 1; // Assume that filename is mapped to integer.
}
static int create(String filename)
{
return 2; // Assume that filename is mapped to integer.
}
static void close(int fileHandle)
{
System.out.println("closing file: " + fileHandle);
}
static void copy(int fileHandleSrc, int fileHandleDst) throws IOException
{
System.out.println("copying file " + fileHandleSrc + " to file " +
fileHandleDst);
if (Math.random() < 0.5)
throw new IOException("unable to copy file");
System.out.println("After exception");
}
}
the output that I expect is
copying file 1 to file 2
I/O error: unable to copy file
closing file: 1
closing file: 2
However sometimes I get this expected output and at other times I get the following output:
copying file 1 to file 2
closing file: 1
closing file: 2
I/O error: unable to copy file
and sometimes even this output:
I/O error: unable to copy file
copying file 1 to file 2
closing file: 1
closing file: 2
and whether I get the first, second or third output seems to happen randomly during every execution. I found THIS POST that apparently talks about the same problem, but I still don't understand why I sometimes get output 1, 2 or 3. If I understand this code correctly then output 1 should be what I get every time (the exception occurs). How do I ensure that I get output 1 consistently, or be able to tell when I will be getting output 1 or when I will be getting output 2 or 3?
The issue is that you are writing some output to System.out
and some to System.err
. These are independent streams, with independent buffering. The timing of when they are flushed is, as far as I know, not specified.
The short of it is that when writing to different streams, you cannot use the order in which the output shows up to determine the order in which the calls to println()
occurred. Note that the output to System.out
always appears in the expected order.
As far as order of execution, the body of the try
is executed first. If it throws an exception, the body of the appropriate catch
clause is then executed. The finally
block is always executed last.
First execute Try
block if it is success finally will execute, if try
block fail then catch
will execute and finally
execute. What ever happen finally block will execute.
But
If you call System.exit(0)
finally block not executed
The thing with exception handling using try catch block is that the control will go inside try if any exception it will get inside catch block. But the control will go to final block every time it executs.
You are writing your error message to both stdout and stderr. They have different buffers, so there is no guarantee that the output you see will be in the same order as you created it, between the two output streams.
Since I can see no errors in your code (although the superfluous return;
in your catch
segment stuck in my craw a little bit), let me suggest that you write all of your messages to stderr, and see if the message order is a little more in line with what you were expecting.
You have one glitch in your example which I would remove. You are writing to both System.out and System.err and expection your console to synchronize both streams correctly. To remove side effects I would just use one stream here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With