The FileInputStream(String filename)
constructor creates an enter stream to the file recognized by filename
. This constructor throws FileNotFoundException
when the file doesn’t exist, refers to a listing, or one other associated drawback happens. The FileOutputStream(String filename)
constructor creates an output stream to the file recognized by filename
. It throws FileNotFoundException
when the file exists however refers to a listing, doesn’t exist and can’t be created, or one other associated drawback happens.
FileInputStream
supplies an int learn()
methodology to learn one byte and return it as a 32-bit integer. This methodology returns -1 on end-of-file. FileOutputStream
supplies a void write(int b)
methodology to jot down the byte within the decrease 8 bits of b
. Both methodology throws IOException
when one thing goes unsuitable.
The majority of the instance is a whereas
loop that repeatedly learn()
s the subsequent byte from the enter stream and write()
s that byte to the output stream, till learn()
indicators end-of-file.
The strive
block’s file-copy logic is simple to observe as a result of this logic isn’t mixed with exception-checking code (if
checks and associated throw
statements hidden within the constructors and strategies), exception-handling code (which is executed in a number of related catch
blocks), and cleanup code (for closing the supply and vacation spot information; this code is relegated to an related lastly
block). In distinction, C’s lack of the same exception-oriented framework leads to extra verbose code, as illustrated by the next excerpt from a bigger C cp
software (on this article’s code archive) that copies a supply file to a vacation spot file:
if ((fpsrc = fopen(argv[1], "rb")) == NULL)
{
fprintf(stderr, "unable to open %s for readingn", argv[1]);
return;
}
if ((fpdst = fopen(argv[2], "wb")) == NULL)
{
fprintf(stderr, "unable to open %s for writingn", argv[1]);
fclose(fpsrc);
return;
}
whereas ((c = fgetc(fpsrc)) != EOF)
if (fputc(c, fpdst) == EOF)
{
fprintf(stderr, "unable to jot down to %sn", argv[1]);
break;
}
On this instance, the file-copy logic is more durable to observe as a result of the logic is intermixed with exception-checking, exception-handling, and cleanup code:
- The 2
== NULL
and one== EOF
checks are the equal of the hiddenthrow
statements and associated checks. - The three
fprintf()
perform calls are the exception-handling code whose Java equal can be executed in a number ofcatch
blocks. - The
fclose(fpsrc);
perform name is cleanup code whose Java equal can be executed in alastly
block.
Utilizing catch blocks to catch exceptions
Java’s exception-handling functionality is predicated on catch
blocks. This part introduces catch
and varied catch
blocks.
The catch block
Java supplies the catch
block to delimit a sequence of statements that deal with an exception. A catch
block has the next syntax:
catch (throwableType throwableObject)
{
// a number of statements that deal with an exception
}
The catch
block is much like a constructor in that it has a parameter listing. Nevertheless, this listing consists of just one parameter, which is a throwable kind (Throwable
or considered one of its subclasses) adopted by an identifier for an object of that kind.
When an exception happens, a throwable is created and thrown to the JVM, which searches for the closest catch
block whose parameter kind straight matches or is the supertype of the thrown throwable object. When it finds this block, the JVM passes the throwable to the parameter and executes the catch
block’s statements, which might interrogate the handed throwable and in any other case deal with the exception. Contemplate the next instance:
catch (FileNotFoundException fnfe)
{
System.err.println(fnfe.getMessage());
}
This instance (which extends the earlier strive
block instance) describes a catch
block that catches and handles throwables of kind FileNotFoundException
. Solely throwables matching this sort or a subtype are caught by this block.
Suppose the FileInputStream(String filename)
constructor throws FileNotFoundException
. The JVM checks the catch
block following strive
to see if its parameter kind matches the throwable kind. Detecting a match, the JVM passes the throwable’s reference to fnfe
and transfers execution to the block. The block responds by invoking getMessage()
to retrieve the exception’s message, which it then outputs.
Specifying a number of catch blocks
You’ll be able to specify a number of catch
blocks after a strive
block. For instance, take into account this bigger excerpt from the aforementioned Copy
software:
FileInputStream fis = null;
FileOutputStream fos = null;
{
fis = new FileInputStream(args[0]);
fos = new FileOutputStream(args[1]);
int c;
whereas ((c = fis.learn()) != -1)
fos.write(c);
}
catch (FileNotFoundException fnfe)
{
System.err.println(fnfe.getMessage());
}
catch (IOException ioe)
{
System.err.println("I/O error: " + ioe.getMessage());
}
The primary catch
block handles FileNotFoundException
s thrown from both constructor. The second catch
block handles IOException
s thrown from the learn()
and write()
strategies.
When specifying a number of catch
blocks, don’t specify a catch
block with a supertype earlier than a catch
block with a subtype. For instance, don’t place catch (IOException ioe)
earlier than catch (FileNotFoundException fnfe)
. In case you do, the compiler will report an error as a result of catch
would additionally deal with
(IOException ioe)FileNotFoundException
s, and catch (FileNotFoundException
would by no means have an opportunity to execute.
fnfe)
Likewide, don’t specify a number of catch
blocks with the identical throwable kind. For instance, don’t specify two catch (IOException ioe) {}
blocks. In any other case, the compiler stories an error.
Utilizing lastly blocks to scrub up exceptions
Whether or not or not an exception is dealt with, you might must carry out cleanup duties, resembling closing an open file. Java supplies the lastly
block for this objective.
The lastly
block consists of key phrase lastly
adopted by a brace-delimited sequence of statements to execute. It might seem after the ultimate catch
block or after the strive
block.
Cleansing up in a try-catch-finally context
When sources have to be cleaned up and an exception isn’t being thrown out of a way, a lastly
block is positioned after the ultimate catch
block. That is demonstrated by the next Copy
excerpt:
FileInputStream fis = null;
FileOutputStream fos = null;
strive
{
fis = new FileInputStream(args[0]);
fos = new FileOutputStream(args[1]);
int c;
whereas ((c = fis.learn()) != -1)
fos.write(c);
}
catch (FileNotFoundException fnfe)
{
System.err.println(fnfe.getMessage());
}
catch (IOException ioe)
{
System.err.println("I/O error: " + ioe.getMessage());
}
lastly
{
if (fis != null)
strive
{
fis.shut();
}
catch (IOException ioe)
{
// ignore exception
}
if (fos != null)
strive
{
fos.shut();
}
catch (IOException ioe)
{
// ignore exception
}
}
If the strive
block executes with out an exception, execution passes to the lastly
block to shut the file enter/output streams. If an exception is thrown, the lastly
block executes after the suitable catch
block.
FileInputStream
and FileOutputStream
inherit a void shut()
methodology that throws IOException
when the stream can’t be closed. For that reason, I’ve wrapped every of fis.shut();
and fos.shut();
in a strive
block. I’ve left the related catch
block empty for instance the frequent mistake of ignoring an exception.
An empty catch
block that’s invoked with the suitable throwable has no method to report the exception. You would possibly waste numerous time monitoring down the exception’s trigger, solely to find that you could possibly have detected it sooner if the empty catch
block had reported the exception, even when solely in a log.
Cleansing up in a try-finally context
When sources have to be cleaned up and an exception is being thrown out of a way, a lastly
block is positioned after the strive
block: there are not any catch
blocks. Contemplate the next excerpt from a second model of the Copy
software:
public static void principal(String[] args)
{
if (args.size != 2)
{
System.err.println("utilization: java Copy srcfile dstfile");
return;
}
strive
{
copy(args[0], args[1]);
}
catch (IOException ioe)
{
System.err.println("I/O error: " + ioe.getMessage());
}
}
static void copy(String srcFile, String dstFile) throws IOException
{
FileInputStream fis = null;
FileOutputStream fos = null;
strive
{
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(dstFile);
int c;
whereas ((c = fis.learn()) != -1)
fos.write(c);
}
lastly
{
if (fis != null)
strive
{
fis.shut();
}
catch (IOException ioe)
{
System.err.println(ioe.getMessage());
}
if (fos != null)
strive
{
fos.shut();
}
catch (IOException ioe)
{
System.err.println(ioe.getMessage());
}
}
}
The file-copying logic has been moved right into a copy()
methodology. This methodology is designed to report an exception to the caller, but it surely first closes every open file.
This methodology’s throws
clause solely lists IOException
. It isn’t crucial to incorporate FileNotFoundException
as a result of FileNotFoundException
subclasses IOException
.
As soon as once more, the lastly
clause presents numerous code simply to shut two information. Within the second a part of this sequence, you’ll study concerning the try-with-resources
assertion, which obviates the necessity to explicitly shut these information.
In conclusion
This text launched you to the fundamentals of Java’s conventional exception-oriented framework, however there’s way more to know. The second half of this tutorial introduces Java’s extra superior exception-oriented language options and library varieties, together with try-with-resources
.