java.util.NoSuchElementException when using Scanner.next() - java

Java noob working on a project where I'm supposed to display data obtained from a text file onto grids. Project is essentially written, but output displays this exception:
run:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at inputOutput.ReadDataFile.populateData(ReadDataFile.java:50)
at boggle.Boggle.main(Boggle.java:27)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
Boggle.java:27 links to a line of code in the main method of my superclass Boggle.java. The line is supposed to call one of the methods in my class ReadDataFile.java. The line reads dataRead.populateData(); (//2. on the comments below), and in context the main method looks like:
public static void main(String[] args) { //main() method begins
// TODO code application logic here
ReadDataFile dataRead = new ReadDataFile("BoggleData.txt"); //1. instance of class ReadDataFile created
dataRead.populateData(); //2. populateData() method called
boggleData = dataRead.getData(); //3. member variable set equal to getData() method
Board boggleBoard = new Board(boggleData); //4. instance of class Board created, passing data as argument
boggleBoard.shakeDice(); //5. shakeDice() method called
} //main() method ends
ReadDataFile.java:50 links to a line in a method called populateData() inside of my subclass ReadDataFile.java. The line is input.next(); and it's in the finally component of a try-catch-finally I created for the class. In context, the populateData() method looks like:
public void populateData(){ //populateData() method begins
try{ //try begins
URL url = getClass().getResource(dataFile); //1. instance of class URL created from file name
File file = new File(url.toURI()); //2. instance of class File based on url
input = new Scanner(file); //3. member variable initialized based on file
while(input.hasNext()){ //4. while loop goes through data file
data.add(input.next()); //a. data from file added to ArrayList
}
} //try ends
catch(Exception ex){ //catch begins
System.out.println(ex.toString());
ex.printStackTrace();
} //catch ends
finally{ //finally begins
input.next();
} //finally ends
} //populateDate() method ends
Basically, I'm having trouble figuring out how I can get around this exception. The actual goal of the project is to display data in grids, but I only get a notice that an exception has been found in the output. The code compiles fine, so I'm not worried about misplaced semicolons or incorrect data types. I'm new to the Java language, and while books and other stackoverflow questions have solved some of my problems, this exception has gotten me stuck.
Would anybody be able to provide some feedback on just what I need to do to get around the exception showing up in my output, what's causing it, or at least steer me in the right direction? I'd really appreciate any helpful comments. Thanks.

Your exception stack-trace shows where the problem is:
at inputOutput.ReadDataFile.populateData(ReadDataFile.java:50)
At line 50 you have this:
finally{ //finally begins
input.next();
}
The problem is that you have already exhausted the file with a loop you previously executed:
while(input.hasNext()){ //4. while loop goes through data file
data.add(input.next()); //a. data from file added to ArrayList
}

I think you meant to close in your finally.
finally{ //finally begins
input.next();
}
should (almost certainly) be
finally{
input.close();
}
Or you could use try-with-resources to close your Scanner like
public void populateData(String dataFile) {
try {
URL url = getClass().getResource(dataFile);
File file = new File(url.toURI());
try (Scanner input = new Scanner(file)) {
while (input.hasNext()) {
data.add(input.next());
}
}
} catch (Exception ex) {
System.out.println(ex.toString());
ex.printStackTrace();
}
}

Related

Java I/O File Not Found

Currently trying to write a program to take input from a file and store it in an array. However, whenever I try to run the program the file cannot be found (despite file.exists() and file.canRead() returning true).
Here is my code:
public void getData (String fileName) throws FileNotFoundException
{
File file = new File (fileName);
System.out.println(file.exists());
System.out.println(file.canRead());
System.out.println(file.getPath());
Scanner fileScanner = new Scanner (new FileReader (file));
int entryCount = 0; // Store number of entries in file
// Count number of entries in file
while (fileScanner.nextLine() != null)
{
entryCount++;
}
dirArray = new Entry[entryCount]; //Create array large enough for entries
System.out.println(entryCount);
}
public static void main(String[] args)
{
ArrayDirectory testDirectory = new ArrayDirectory();
try
{
testDirectory.getData("c://example.txt");
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
(In it's current state the method is only designed to count the number of lines and create the array)
The console output is as follows: true true c:/example.txt
The program seems to throw a 'FileNotFoundException' on the line where the scanner is instantiated.
One thing I have noticed when checking the 'file' object when debugging is although it's 'path' variable has the value "c:\example.txt", it's 'filePath' value is null. Not sure if this is relevant to the issue or not
EDIT: After Brendan Long's answer I have updated the 'catch' block. The stack trace reads as follows:
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at assignment2.ArrayDirectory.getData(ArrayDirectory.java:138)
at assignment2.ArrayDirectory.main(ArrayDirectory.java:193)
Seemingly the scanner doesn't recognize the file and thus can't find the line
This code probably doesn't do what you want:
try
{
testDirectory.getData("c://example.txt");
}
catch (Exception ex)
{
new FileNotFoundException("File not found");
}
If you catch any exception, you run the constructor for a FileNotFoundException and then throw it away. Try doing this:
try
{
testDirectory.getData("c://example.txt");
}
catch (Exception ex)
{
ex.printStackTrace();
}
According to the javadoc for Scanner, nextLine() throws this exception when there is no more input. Your program seems to expect it to return null, but that's now how it works (unlike, say, BufferedReader which does return null at the end of the input). Use hasNextLine to make sure there's another line before using nextLine.

What is the best way to handle an exception for an invalid file?

I have a java class where a user provides a file path and if the path doesn't exist I ask them to try again. My professor says we should use an exception to handle this.
Here is a snippet of how I'm currently doing it:
public class SalesUtil {
public static void processSales() {
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter sales file name: ");
String salesFile = keyboard.nextLine();
try {
Scanner scanFile = new Scanner(new File(salesFile));
//do stuff
}
} catch(FileNotFoundException fnfe) {
System.out.println("Invalid file name supplied, please try again.");
processSales();
}
}
}
Well in the do stuff section, I'm calculating values and printing data to the console. If I enter the correct file name correctly on the first try all the data is correct. If it is incorrect one or more times the data is not correct.
I imagine this is because of adding function calls on top of my initial stack and never 'getting out' of the initial stack while supplying subsequent stack calls until the correct file is supplied?
I'm still new to java and would appreciate some tips in understanding how to solve this using an exception.
The FileNotFoundException is the correct one to catch, however I gather that you're worried about the stacks building up? I tested reading back the file after multiple failed attempts and it was fine. The recursive call is at the end of the method so it is the last line of code and therefore the stacks shouldn't have any effect.
However, if you want, you could use a while loop instead of recursion to avoid stack buildup:
public static void processSales() {
Scanner scanFile = null;
Scanner keyboard = new Scanner(System.in);
while (scanFile == null) {
System.out.println("Enter sales file name: ");
String salesFile = keyboard.nextLine();
try {
scanFile = new Scanner(new File(salesFile));
while (scanFile.hasNextLine()) {
System.out.println(scanFile.nextLine());
}
} catch(FileNotFoundException fnfe) {
System.out.println("Invalid file name supplied, please try again.");
}
}
}
use the file.exist() method to check, if that what you want to do is to make sure it exist then this is the codes:
File sfile = new File(salesFile);
if (sfile.exists()) {
// ok, file exist do something.
...
}
On the other hand, when you say "invalid file" could be anything, if it is bad filename, then it is another animal (well, different exeception)...
To use try/catch for a readonly file then:
try {
FileInputStream sfile = new FileInputStream(salesFile);
...
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}

Error message being displayed before correct output shown in Java

I am implementing a try catch block to confirm a file exists before reading data from the file, then using that data to print out a menu to eventually run a menu-driven application. It appears as though I am correctly reading from the file, however, when I run the driver class, it displays the error message contained in the catch block before it correctly displays the output menu as desired.
public static void main(String[] args)
{
try
{
Scanner input = new Scanner(new File("concerts.txt"));
ConcertEvent concert1 = new ConcertEvent(input);
ConcertEvent concert2 = new ConcertEvent(input);
ConcertEvent concert3 = new ConcertEvent(input);
System.out.println("Redbird Concert Hall");
System.out.println();
System.out.println("Please choose your concert:");
System.out.println("1. " + concert1.getBandName());
System.out.println("2. " + concert2.getBandName());
System.out.println("3. " + concert3.getBandName());
System.out.println("4. Quit");
System.out.println();
}
catch(Exception e)
{
System.out.println("Error: File Not Found");
}
I attached the constructor used in creating the three instances of ConcertEvent
public ConcertEvent(Scanner input)
{
try
{
bandName = input.nextLine();
showCapacity = input.nextInt();
ticketPrice = input.nextDouble();
input.nextLine();
}
catch(Exception e)
{
System.out.println("Error: file not found");
}
}
desired output:
Redbird Concert Hall
Please choose your concert:
1. Maroon 5
2. One Direction
3. Pearl Jam
4. Quit
actual output:
Error: file not found (Exception found in the catch statement of the
Redbird Concert Hall
Please choose your concert:
1. Maroon 5
2. One Direction
3. Pearl Jam
4. Quit
I realize it's probably not correct to have the try catch block in the constructor, however when I remove the try catch block, the actual output changes to...
Error: File Not Found (the exception found in the catch statement of the main method)
The catch block triggered is the one in your ConcertEvent constructor, and it may be that the file cannot be found or is not accessible, or etc. (you won't know until you print the stack trace).
If you want your prompt output to take place before any file operations, just move it to before the try block in your main method.
Also, as Chandranshu mentions, catching specific exceptions will help you nail down the issue.
Finally, it doesn't make much sense to have your main method stating a try/catch statement for a constructor that also has a try/catch statement, reasonably for the same Exception(s).
Either throw the Exceptions in the constructor, or remove the try/catch in your main method.
For instance, as FileNotFoundException is a checked exception, you could throw it in your constructor (and must declare a throws statement in its signature), then catch it in main, then printStackTrace in your catch statement in main).

Reading arraylist from a .txt file

I have an app where user inputs certain words and those words are saved to a .txt file on the device. Then I'm creating arraylist from that .txt file. This is the code:
try {
Scanner s = new Scanner(recordedFiles);
recordedFilesArray = new ArrayList<String>();
while (s.hasNext()){
recordedFilesArray.add(s.next());
}
s.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Now, the problem is that this puts each word to arraylist, not each line. So if user inputs (for example) 'test1', it'll add it to arraylist as test1 (which is fine), but if user inputs 'test 1' (with a space), 'test' and '1' will be added to arraylist as seperate elements.
Showing an example how it should work:
How text file looks like (example)
test 1
test 2
test 3
How arraylist looks like now:
test
1
test
2
test
3
How arraylist should look like:
test 1
test 2
test 3
So my question is; how do I add LINES to arraylist, not seperate words from a .txt file
Use .nextLine() which functions as follows:
Advances this scanner past the current line and returns the input that
was skipped. This method returns the rest of the current line,
excluding any line separator at the end. The position is set to the
beginning of the next line.
As Matt Ball has indicated the while loop should use hasNextLine() instead of hasNext()
try {
Scanner s = new Scanner(recordedFiles);
recordedFilesArray = new ArrayList<String>();
while (s.hasNextLine()){
recordedFilesArray.add(s.nextLine());
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
s.close(); //close file on success or error
}
Documentation
Use Scanner#hasNextLine() with Scanner#nextLine(), not Scanner#hasNext() with Scanner#next().
You can use scanner.nextLine();
Instead of using scanner.next(); use scanner.nextLine();

Setting number in a file to 0 when pressing a JButton

In the starting menu for my game I wan't to make it so that when you press the "Continue" button you get the score that you had the last time you played. I have already fixed the code that saves the score and the code that loads the score so it isn't any problems with the continue button.
But for the "New Game" button I'm having some difficulties. When that button is pressed I need to make the file that stores the score reset (set the number inside it to 0 instead of the last score). I have tried to have this code inside the ActionListener for the button but it doesn't set the text inside the .dat file to 0 but it adds a 0 to the end.
try{
String zero = "0";
byte[] reset = zero.getBytes();
player.getFile().write(reset);
}catch (IOException ex){
}
I have also tried player.setScore("0"); which I use to add 10 score every time an enemy dies but then it will still get the score from the .dat file.
This is the two method inside the player class that handels the loading and saving of the file.
public void save(){
try{
getScore = new File("Score.dat");
scoreFile = new FileOutputStream(getScore);
byte[] saveScore = score.getBytes();
scoreFile.write(saveScore);
}catch(FileNotFoundException ex){
}catch(IOException ex){
}
}
public void load(){
try{
br = new BufferedReader(new FileReader("Score.dat"));
score = br.readLine();
}catch (FileNotFoundException ex){
}catch(IOException ex){
}
}
I have also tried to only run the load() method if I press the "Continue" button and not the "New Game" button but the I get a java.lang.NullPointerException error.
Your code is hiding all the relevant exceptions, which will make it very hard to figure out what's going on - put something like ex.printStackTrace(); in the catch blocks so you can see if exceptions are thrown. I would imagine in your case, the bytes aren't getting written because you aren't closing or flushing the stream.
Regardless, you probably want to use something like a PrintWriter with the file instead, rather than writing raw bytes:
PrintWriter writer = new PrintWriter(new File("file.txt"));
writer.println("0");
writer.close();
If getFile() returns a FileWriter, then you probably have to close and reopen the file each time, and use the constructor that lets you indicate that you do NOT want it to append additional data.

Categories

Resources