Structures
Structures

Reputation: 111

How to loop a try catch statement?

How do you loop a try/catch statement? I'm making a program that is reading in a file using a Scanner and it's reading it from the keyboard. So what I want is if the file does not exist, the program will say "This file does not exist please try again." then have the user type in a different file name. I have tried a couple different ways to try an do this but, all of my attempts end up with the program crashing.

Here is what I have

    try {
        System.out.println("Please enter the name of the file: ");
        Scanner in = new Scanner(System.in);
        File file = new File(in.next());
        Scanner scan =  new Scanner(file);
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("File does not exist please try again. ");
    }

Upvotes: 5

Views: 78097

Answers (5)

Stephen C
Stephen C

Reputation: 719616

If you want to retry after a failure, you need to put that code inside a loop; e.g. something like this:

boolean done = false;
while (!done) {
    try {
        ...
        done = true;
    } catch (...) {
        ...
    }
}

(A do-while is a slightly more elegant solution.)

However, it is BAD PRACTICE to catch Exception in this context. It will catch not only the exceptions that you are expecting to happen (e.g. IOException), but also unexpected exceptions (like NullPointerException and so on) that would be symptoms of bugs in your program.

It is better to catch the exceptions that you are expecting (and can handle), and allow any others to propagate. In your particular case, catching FileNotFoundException is sufficient. (That is what the Scanner(File) constructor declares.) If you weren't using a Scanner for your input, you might need to catch IOException instead.


I must correct a serious mistake in the top-voted answer.

do {
    ....
} while (!file.exists());

This is incorrect because testing that the file exists is not sufficient:

  • the file might exist but the user doesn't have permission to read it,
  • the file might exist but be a directory,
  • the file might exist but be unopenable due to hard disc error, or similar
  • the file might be deleted/unlinked/renamed between the exists() test succeeding and the subsequent attempt to open it.

Note that:

  1. File.exists() ONLY tests that a file system object exists with the specified path, not that it is actually a file, or that the user has read or write access to it.
  2. There is no way to test if an I/O operation is going to fail due to an hard disc errors, network drive errors and so on.
  3. There is no solution to the open vs deleted/unlinked/renamed race condition. While it is rare in normal usage, this kind of bug can be targeted if the file in question is security critical.

The correct approach is to simply attempt to open the file, and catch and handle the IOException if it happens. It is simpler and more robust, and probably faster. And for those who would say that exceptions should not be used for "normal flow control", this isn't normal flow control ...

Upvotes: 13

andand
andand

Reputation: 17507

Try something like this:

boolean success = false;

while (!success)
{
    try {
        System.out.println("Please enter the name of the file: ");
        Scanner in = new Scanner(System.in);
        File file = new File(in.next());
        Scanner scan =  new Scanner(file);
        success = true;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        System.out.println("File does not exist please try again. ");
    }
}

Upvotes: 2

Stalzer
Stalzer

Reputation: 104

Check if the file exists using the API.

String filename = "";

while(!(new File(filename)).exists())
{
    if(!filename.equals("")) System.out.println("This file does not exist.");
    System.out.println("Please enter the name of the file: ");
    Scanner in = new Scanner(System.in);
    filename = new String(in.next();        
}
File file = new File(filename);
Scanner scan =  new Scanner(file);

Upvotes: 0

James Montagne
James Montagne

Reputation: 78750

You can simply wrap it in a loop:

while(...){

    try{

    } catch(Exception e) {

    }

}

However, catching every exception and just assuming that it is due to the file not existing is probably not the best way of going about that.

Upvotes: 1

squiguy
squiguy

Reputation: 33380

Instead of using a try catch block, try a do while loop checking if the file exists.

do {

} while ( !file.exists() );

This method is in java.io.File

Upvotes: 8

Related Questions