I am trying to output a file scanner object from my method. This is a school assignment and I am specifically instructed to NOT throw any exceptions, but use try/catch instead. The assignment requires that the command line prompt the user for a file to scan. If the file does not exist, we are supposed to tell the user, then prompt them for a file again. If the file does exist, then the method returns a scanner object that scans the file.
My code works, but it is not clean. It involves 2 methods. This is my code so far:
public static Scanner getInputScanner (Scanner console) {
File inputFile = null;
Scanner input = null;
try {
inputFile = getFile(inputFile, console);
input = new Scanner (inputFile);
return input;
} catch (FileNotFoundException e) {
try {
return input = new Scanner (getFile (inputFile, console));
} catch (FileNotFoundException f) {
System.out.println("An error has occured.");
return input;
}
}
}
public static File getFile (File inputFile, Scanner console) {
System.out.println("Enter input file: ");
inputFile = new File (console.nextLine());
while (!inputFile.exists()) {
System.out.println("File does not exist.");
System.out.print("Enter input file: ");
inputFile = new File (console.nextLine());
}
return inputFile;
}
The problem with the code is that the output looks like this:
Enter input file:
File does not exist.
Enter input file:
It then is waiting for the user's input. I don't want the output to have the 2 lines of code before the last line though.
Can anybody explain why my code is outputting these 2 lines?
Also, is there a simpler solution to getting an input file without throwing the FileNotFoundException?
Thanks!
If I understand correctly,
your program outputs these lines when you run it,
no matter what,
without you getting a chance to actually enter a filename.
Enter input file:
File does not exist.
And then the programs asks you again:
Enter input file:
And you don't want the first two lines above, right?
This can happen for example if the Scanner console you received has an unread newline in it.
You haven't posted that part of the code,
so it's hard to tell, but this is a common gotcha with Scanner.
Before calling getInputScanner,
make sure the Scanner console is ready to use,
with no unread garbage still buffered in it.
As for the second part of your question,
yes this can be written simpler and better, for example:
public static Scanner getInputScanner(Scanner console) {
try {
File inputFile = getExistingFile(console);
return new Scanner(inputFile);
} catch (FileNotFoundException e) {
throw new AssertionError("The file is expected to exist (was supposed to be verified earlier)");
}
}
public static File getExistingFile(Scanner console) {
while (true) {
System.out.println("Enter input file: ");
File inputFile = new File(console.nextLine());
if (inputFile.exists()) {
return inputFile;
}
System.out.println("File does not exist.");
}
}
It execute below line as soon the getFile() being called.
System.out.print("Enter input file: ");
Since no file exist, the below lines keeps on executing :
while (!inputFile.exists()) {
System.out.println ("File does not exist.");
System.out.print("Enter input file: ");
You can use throws() instead of try/catch, then caller will take care of exception.
Had to consume whatever junk was being carried over from the scanner by inserting a Scanner.nextLine() before getting user input. Final code looks like this:
public static Scanner getInputScanner(Scanner console) {
try {
File inputFile = getExistingFile(console);
return new Scanner(inputFile);
} catch (FileNotFoundException e) {
throw new AssertionError("The file is expected to exist (was supposed to be verified earlier)");
}
}
public static File getExistingFile(Scanner console) {
while (true) {
console.nextLine();
System.out.println("Enter input file: ");
File inputFile = new File(console.nextLine());
if (inputFile.exists()) {
return inputFile;
}
System.out.println("File does not exist.");
}
}
Related
I'm trying to code for a file not found exception in a while loop so that the program continues prompting the user for the file (test.txt). I wrote a try/catch block inside a while loop. However, when I delete the input file (test.txt), the program should catch this error and print "Error, cannot locate the 'test.txt' file, please try again:" and allow the user to input another file name. However, the program crashes and gives me a FileNotFoundException.
In this case it's probably better to ask for permission rather than forgiveness (e.g. check if the file exists before attempting to read it).
File file = new File("test_input.txt");
if (file.exists()) {
FileReader fileReader = new FileReader(file);
}
You should add another try and catch for the Scanner
// prompt user for name for output textfile
System.out.println();
System.out.print("What would you like to call your output file: ");
String outputName = inputReader.nextLine();
// scanner and printwriter objects for reading text file
try {
Scanner in = new Scanner(correctInputfile);
PrintWriter out = new PrintWriter(outputName);
// read input (values) and write the output (average)
// messages triggered by successful location of files.
if (fileName.equalsIgnoreCase(("test_input.txt"))) {
// code logic
}
} catch (FileNotFoundException ex) {
System.out.println();
System.out.println("***** ERROR *****");
System.out.println("\nCannot locate the input file " + "'" + fileName + "'" + "on your computer - please try again.");
System.out.print("\nInput file name (from your computer): ");
}
In your code, two lines raise FileNotFoundExceptions that you are not catching:
// scanner and printwriter objects for reading text file
Scanner in = new Scanner(correctInputfile);
PrintWriter out = new PrintWriter(outputName);
// read input (values) and write the output (average)
You can replace them with the following, and the code (should) work.
Scanner in = null;// Initialize to null, so they don't raise warnings.
PrintWriter out = null;
try { // Surround with try/catch to get the exception
in = new Scanner(correctInputfile);
out = new PrintWriter(outputName);
}catch(FileNotFoundException e){
/*TODO: something about the exception here!
Make sure the Scanner and PrintWriter get
properly initialized with valid file names.*/
}
I am not sure while am receiving a no such element exception. It seems to be an issue with the scanner not reading my file correctly, but I am not sure where I am going wrong.
I am reading a file, then using the scanner to go line by line. But I get unusual behavior, such as missing lines or filenotfound exceptions when I try to do it.
public static void readMylifeLikeABook(String fileName,int maxItems) {
// Read file line by line with different elements on each line
int bookCount=0;
int movieCount = 0;
Book [] bookItem =new Book[maxItems];
Movie [] movieItem =new Movie[maxItems];
try {
File file = new File(fileName);
Scanner scanner = new Scanner(file);
Scanner line;
while (scanner.hasNext() && ((bookCount+movieCount)<maxItems)) {
line = new Scanner(scanner.nextLine()); // scan next line
if (line.next().contains("Movie")){
movieItem[movieCount]= new Movie();
movieItem[movieCount].setMediaType("Movie");
movieItem[movieCount].setTitle(scanner.nextLine());
movieItem[movieCount].setRef(scanner.nextLine());
movieItem[movieCount].setPrice(Double.valueOf(scanner.nextLine()));
movieItem[movieCount].setDirector(scanner.nextLine());
movieItem[movieCount].setActor(scanner.nextLine());
System.out.println(movieItem[movieCount].getTitle());
movieCount++;
line.close(); // close line
}
else if (scanner.next().contains("Book")){
bookItem[bookCount]= new Book();
bookItem[bookCount].setMediaType("Book");
bookItem[bookCount].setTitle(scanner.nextLine());
bookItem[bookCount].setRef(scanner.nextLine());
bookItem[bookCount].setPrice(Double.valueOf(scanner.nextLine()));
bookItem[bookCount].setAuthor(scanner.nextLine());
System.out.println(bookItem[bookCount].getTitle());
bookCount++;
line.close(); // close line
}
}
scanner.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
//System.out.println(count);
for (int i=0;i<(bookCount+movieCount);i++) {
System.out.println(bookItem[i] +"\n\n "+ movieItem[i]);
}
}
Hmm, is it possible if you can provide the file being read? This can very well be a problem with that File as if the Scanner object does not a following line to be read, it will throw an exception. Make sure the file has the needed amount of lines.
You call line.next() immediately after constructing line. Do you need to do this? If so, perhaps you need to call hasNext() first to ensure there's a token there.
(I'm pretty sure line.next() throws a NoSuchElementException if there's no token.)
Also, check your code against the file format. Are there blank lines in your file?
I am writing a piece of code that returns a scanner for a user-input file name. Here's the code:
public static Scanner getInputScanner(Scanner console) {
System.out.print("Enter input file: ");
String fileName = "";
try {
fileName = console.nextLine();
File f = new File(fileName);
} catch (FileNotFoundException e) {
while (!(new File(fileName)).exists()) {
System.out.println(fileName + " (No such file or directory)");
System.out.print("Enter input file: ");
fileName = console.nextLine();
}
}
File f = new File(fileName);
return new Scanner(f);
}
I am getting two errors:
Compression.java:49: error: exception FileNotFoundException is never thrown in body of corresponding try statement
} catch (FileNotFoundException e) {
^
Compression.java:57: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
return new Scanner(f);
I can't figure out why the try block isn't throwing an exception, since the user could input an invalid file name.
Thanks for any help.
EDIT: changed the FileNotFoundException to a NullPointerException and that fixed the first problem. Now, however, I get an error that my return statement is throwing an unreported FileNotFoundException. But this code wouldn't execute unless the file is valid, right? Is Java blind to this, and requires I catch the exception anyway?
The FileNotFoundException is neither thrown by Scanner#nextLine() nor by creating a new File object (File#new(String)). Both functions do nothing that is related to file I/O.
Scanner.nextLine() operates on an alread existing input source
File#new() creates simply a new File object that points (file name) to an (maybe existing) actual file.
The creation of a new Scanner object in contrast, involves creating a new InputStream, so it actually touches the supplied file by opening it.
From java.util.Scanner:
public Scanner(File source) throws FileNotFoundException {
this((ReadableByteChannel)(new FileInputStream(source).getChannel()));
}
The documentation clearly states that the File(String pathname) constructor can only throw NullPointerException and NOT FileNotFoundException.
If you want to see if the file name is valid, use f.exists().
return new Scanner(f);
throws error when file is not found, it can't return the scanner(f) . so should be wrapped in try-catch block.
or you need to make the getInputScanner to throw the FileNotFoundException
File f = new File(fileName);
does not throw an exception if the file does not exist. A File object is really just a filename; it does not refer to the actual file. If the file does not exist, you will get an exception when you try to use it.
new Scanner(f) is the part that throws a FileNotFoundException.
You can always call File.exists() before you construct your Scanner and if you use an infinite loop you can simplify your logic and eliminate those errors. Something like,
public static Scanner getInputScanner(Scanner console) {
while (true) {
System.out.print("Enter input file: ");
String fileName = console.nextLine();
File f = new File(fileName);
if (!f.exists()) {
System.out.println(fileName + " (No such file or directory)");
continue;
}
try {
return new Scanner(f);
} catch (FileNotFoundException e) {
// This shouldn't happen.
e.printStackTrace();
System.out.println(fileName + " (No such file or directory)");
}
}
}
Im trying to write a program that will ask for the name of an input file and an output file. It will open the input file and create the output file. It will then read the input file and make a double-spaced copy of the input in the output file.
public class ProgramTest
public static void main (String[] args )
{
Scanner keyboard = new Scanner(System.in);
System.out.println("where to read?");
String in = keyboard.nextLine();
System.out.println("where to write?");
String out = keyboard.nextLine();
Scanner scanner = new Scanner(new File(in));
PrintWriter outputFile = new PrintWriter(out);
}
Thats what I have so far. What I dont know is how to make it do the last part to read the input file and make a double-spaced copy of the input in the output file.
well you can start by reading in the file?
private static void readFile(String inputFile) {
File file = new File(inputFile);
try {
Scanner scan = new Scanner(file);
//for example String s = scan.next(); would store next word
//doulbe d = scan.nextDouble(); would grab next double
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Once you read in the file sore the lines/numbers into variables?? Should not be to hard work with the read file i provided. Also remember what should you read in first ints or strings?
I'm trying to read in a .txt file in but when i use debugger it gets stuck on nextline? Is there some logic error that im doing? It's all being stored into an array through multiple objects:
public static File readFileInfo(Scanner kb)throws FileNotFoundException
{
System.out.println("Enter your file name");
String name = "";
kb.nextLine();
name = kb.nextLine();
File file = new File(name);
return file;
}
The scanner I passed into it is:
Scanner fin = null, kb = new Scanner(System.in);
File inf = null;
inf = FileUtil.readFileInfo(kb);
fin = new Scanner(inf);
You're reading from two different "files" here:
System.in, the standard input (or "terminal"), which you're using to ask the user for a filename
the file with the name you get from the user
When you call name = kb.nextLine();, you're asking the parameter (the Scanner built with System.in) for its next line. Generally, that will actually block ("hang") until it receives another line of input (the filename) from the user. If running from a command line, enter your text into that window; if running in an IDE, switch to the Console tab and enter it there.
As quazzieclodo noted above, you probably only need to call readLine once.
After that, you can open up your second Scanner based on the File that readFileInfo returns, and then you're actually reading from a text file as expected.
Assuming that your intention is to use Scanner to read a text file:
File file = new File("data.txt");
try {
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}