I am currently working on a program for one of my java class and I keep running into a wall with file reading! I am using a JTable to display the information so when the information is read from a file it is added to a row. Whenever there is a blank row the scanner cannot read it and throw an error! i get a java.util.NoSuchElementException on the last scanning line! As of right no i am suing two separate scanners. I had attempted to use the String.split method that that also gave me an error (ArrayIndexOutOfBoundsException: 0). I will post the reading a saving methods below (both two scanner version and split).
private void read() {
try {
Scanner scanner = new Scanner(new File("games.dat"));
scanner.useDelimiter(System.getProperty("line.separator"));
while (scanner.hasNext()) {
String[] tableRow = new String[6];
Scanner recIn = new Scanner(record);
recIn.useDelimiter("\\s*\\|\\s*");
tableRow[0] = recIn.next();
tableRow[1] = recIn.next();
tableRow[2] = recIn.next();
tableRow[3] = recIn.next();
tableRow[4] = recIn.next();
//recIn.next();
recIn.close();
model.addRow(new Object[]{tableRow[0],
tableRow[1], tableRow[2],
tableRow[3], tableRow[4]});
}scanner.close();
scanner = null;
} catch (Exception ex) {
JOptionPane.showConfirmDialog(null, "Could not connect to file! Make sure you are not in zipped file!",
"Warning!", JOptionPane.OK_OPTION,
JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
private void save() {
for (int i = 0; i < model.getRowCount(); i++) {
String data = model.getValueAt(i, 0) + "|" + model.getValueAt(i, 1)
+ "|" + model.getValueAt(i, 2) + "|" + model.getValueAt(i, 3)
+ "|" + model.getValueAt(i, 4) + "|";
games.add(data);
}
try {
for (int i = 0; i < games.size(); i++) {
fileOut.println(games.get(i));
}
fileOut.close();
} catch (Exception ex) {
JOptionPane.showConfirmDialog(null, "Could not connect to file! Make sure you are not in zipped file!",
"Warning!", JOptionPane.OK_OPTION,
JOptionPane.ERROR_MESSAGE);
}
}
recIn.next(); will fail if the line is empty, guard it with hasNext():
Scanner recIn = new Scanner(record);
recIn.useDelimiter("\\s*\\|\\s*");
if (recIn.hasNext()) {
tableRow[0] = recIn.next();
tableRow[1] = recIn.next();
tableRow[2] = recIn.next();
tableRow[3] = recIn.next();
tableRow[4] = recIn.next();
}
This assumes that when there is one element on the record, all of them are there. If this cannot be guaranteed, you need to protect each next() call with hasNext() and decide what to do when you run out of elements in the middle of a record.
Also, you seem to have an infinite loop:
while (scanner.hasNext()) {
// no calls to scanner.next()
}
Did you leave out String record = scanner.next(); from the top of that loop?
From the java.util.Scanner JavaDoc, there is this method, skip():
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html#skip%28java.util.regex.Pattern%29
The last line reads, "Note that it is possible to skip something without risking a NoSuchElementException by using a pattern that can match nothing, e.g., sc.skip("[ \t]*")."
So, perhaps add as the first call of your loop, scanner.skip("[ \t]*);
Related
Hi. I'm having the issue in an error of exception. I don't know what is wrong. But please help me fix this. I'm trying to store data from the file to ArrayList and display the data in the ArrayList. Here, I attached my code and data Code and data source.
the NoSuchElementException appears because you are calling input.nextToken(); while input doesn't have any token.It's due to the last empty line of your file listbook.txt. By deleting this line, the exception shouldn't appear.
A proper manner could be to ensure that you have sufficient tokens to retrieve all your fields for a given line.
public class TextFile
{
public static void main(String[] args)
{
try
{
FileReader read = new FileReader("C:\\Users\\ogawi\\Downloads\\listbook.txt");
BufferedReader bf = new BufferedReader(read);
Book B = new Book();
ArrayList<Book> bookList = new ArrayList<Book>();
String data = null;
StringTokenizer input = null;
while((data = bf.readLine()) != null)
{
input = new StringTokenizer(data,";");
//we ensure that we have enough tokens to retrieve all fields
if(input.countTokens() == 6)
{
String title = input.nextToken();
String author = input.nextToken();
String publisher = input.nextToken();
String genre = input.nextToken();
int year = Integer.parseInt(input.nextToken());
int page = Integer.parseInt(input.nextToken());
B = new Book(title, author, publisher, genre, year, page);
bookList.add(B);
}
}
//This part of code has been moved outside the while loop
//to avoid to print the total content of the array each time
//an element is added
int count=0;
for(int i=0;i<bookList.size();i++)
{
B = (Book)bookList.get(i);
System.out.println(B.toString());
System.out.println("=============================");
count++;
}
System.out.println("Number of Books: " + count);
bf.close();
}
catch(FileNotFoundException fnf)
{ System.out.println(fnf.getMessage());}
catch(EOFException eof)
{ System.out.println(eof.getMessage());}
catch(IOException io)
{ System.out.println(io.getMessage());}
finally
{ System.out.println("System end here..TQ!!");}
}
}
This issue is due to the extra line without book information:
You can see the line 31 and 32 in above figure.
To solve this issue you can add one if condition data.contains(";") . Text file has ; delimiter if we check the condition if given line has ; delimiter then it won't cause an issue.
while ((data = bf.readLine()) != null) {
if (data.contains(";")) {
input = new StringTokenizer(data, ";");
String title = input.nextToken();
String author = input.nextToken();
String publisher = input.nextToken();
String genre = input.nextToken();
int year = Integer.parseInt(input.nextToken());
int page = Integer.parseInt(input.nextToken());
B = new Book(title, author, publisher, genre, year, page);
bookList.add(B);
int count = 0;
for (int i = 0; i < bookList.size(); i++) {
B = (Book) bookList.get(i);
System.out.println(B.toString());
System.out.println("=============================");
count++;
}
System.out.println("Number of Books: " + count);
}
}
Here is the screenshot for successful execution of the code.
I have this code
static String sCurrentLine = null;
/* keyword */
static String keyword = null;
Scanner keywordFile = null, siteFile = null;
try {
keywordFile = new Scanner(new File("/home/mearts/keywords.txt"));
siteFile = new Scanner(new FileReader(fileChooser.getSelectedFile()));
sCurrentLine = siteFile.nextLine().trim();
keyword = keywordFile.nextLine().trim();
while (sCurrentLine != null){
while (keywordFile.hasNext() || keyword == null) {
System.out.println("Line--> " + keyword);
System.out.println("Current here >>" + sCurrentLine);
if (sCurrentLine.contains(keyword)) {
System.out.println("Found it-->> " + keyword);
keyword = keywordFile.nextLine();
System.out.println("next keyword " + keyword);
///* reset search to top of site file */
siteFile = new Scanner(new
FileReader(fileChooser.getSelectedFile()));
sCurrentLine = siteFile.nextLine().trim();
}
else {
sCurrentLine = siteFile.nextLine();
if (sCurrentLine == null) {
break;
}
if (!sCurrentLine.matches(keyword)){
System.out.println("The following keyword " + keyword + " does not exist in file "
+ fileChooser.getSelectedFile());
}
}
} //2nd while loop
}
}
catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
siteFile.close();
keywordFile.close();
}
and i have a text file called keywords which has a list of keywords in it,
but my logic is off an I cannot figure out why.
I think I may need to run the loop one last time but not sure how to do that
My issue is that the last word in the keyword file never gets read in. so the program stops at the 2nd to last element in the text file.
I am not sure that I understand what your code should do.
If I understood correctly your code, your task is to read keywords from a file with keywords and then find all keywords in another file. Is it correct?
You should separate reading keywords from the file and search for them in the file. You should 'load' keywords in a list and then search through the file.
To load keywords in list
keywordFile = new Scanner(new File("/home/mearts/keywords.txt"));
List<String> keywordsList = new ArrayList<>();
while (keywordFile.hasNextLine()) {
keywordsList.add(keywordFile.nextLine());
}
And to search for keywords in the file
siteFile = new Scanner((Readable) new FileReader(fileChooser.getSelectedFile()));
while (siteFile.hasNextLine()) {
String sCurrentLine = siteFile.nextLine().trim();
for (String keyword : keywordsList) {
if (sCurrentLine.contains(keyword)) {
System.out.println("Found it-->> " + keyword);
break;
}
}
System.out.println(
"The following keyword " + keyword + " does not exist in file " + fileChooser.getSelectedFile());
}
I hope this will help :)
This question already has answers here:
Checking if a string is empty or null in Java [duplicate]
(5 answers)
Closed 6 years ago.
Why does my if-else block not detect that gamma is null? Here is my code. It is a Spreadsheet application and this is the save function which loops through all of the cells in the table and writes it to a file. Here is my code:
public void Save () {
String FileName = JOptionPane.showInputDialog("Please enter the name for your file:");
if (FileName == null) {
System.err.println("You didn't enter anything");
} else {
int rows = Table.getRowCount();
int columns = Table.getColumnCount();
int alpha = 0;
int beta = 1;
choicer.setCurrentDirectory(new java.io.File("Desktop"));
choicer.setDialogTitle("Save Document");
choicer.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
choicer.setAcceptAllFileFilterUsed(false);
if (choicer.showSaveDialog(new JPanel()) == JFileChooser.APPROVE_OPTION) {
dir = String.valueOf(choicer.getSelectedFile());
}
File f = new File(dir + "\\" + FileName + ".txt");
try {
fos = new FileOutputStream(f);
osw = new OutputStreamWriter(fos);
w = new BufferedWriter(osw);
for (alpha = 0; alpha <= rows - 1; alpha++) {
for (beta = 1; beta < columns; beta++) {
String gamma = String.valueOf(Table.getValueAt(alpha, beta));
if (gamma != null) {
w.write("<%! " + gamma + " !%> ");
} else {
w.write(" <%! |^-^| !%> ");
}
}
w.write("\n");
}
} catch (IOException e) {
System.err.println("Some prob dude. Too big for me");
} finally {
try {
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I tried the link given by the duplicate thing but that doesn't solve my problem. If I do if(gamma != null && !(gamma.isEmpty)) then only null is written to the file as the value of gamma.
Maybe, gamma is empty but not null:
Change
if (gamma != null)
To
if (gamma != null && !gamma.isEmpty())
There are only three things that I can think of that would cause this. I will get to those in a second. First, what IDE are you using? Do you have the ability to set a breakpoint and watch variables? This will help you in troubleshooting the following.
1. Can you ensure that the first for loop hits?
2. Then, make sure you are getting in the second for loop.
3. Finally, what is the actual value of the string gamma? This is where you need a breakpoint and to inspect that variable when you are expecting it to be null. Likely you will see it is not. That is of course, assuming that your for loops are even letting you get there.
Hope this helps!
For my computer science class I'm making an website username/password program. I decided to use a 2D string array, and it hasn't been working out the best. I tried to make a file reader to read the logins that get written but I keep getting the ArrayIndexOutOfBoundsException error. My file reader code is below, and also included is my login input code. I am just starting Java so I have very basic programming knowledge.
private void fileReader() throws FileNotFoundException {
File inFile = new File(filePath);
try {
Scanner freader = new Scanner(inFile);
while (freader.hasNextLine()) {
for (int j = 1; j <= pass.length; j++) {
pass[j][0] = freader.nextLine();
pass[j][1] = freader.nextLine();
pass[j][2] = freader.nextLine();
}
}
freader.close();
} catch (IOException e) {
System.err.println(e);
System.exit(1);
}
Login input:
private void input() throws InterruptedException, FileNotFoundException {
for (int i = 0; i < pass.length; i ++){
System.out.println(i);
if (i == pass.length){
add();
}
c.print("Please enter the website: ");
pass[i][0] = c.readLine();
c.print("Please enter your username: ");
pass[i][1] = c.readLine();
c.print("Please enter your password: ");
pass[i][2] = c.readLine();
while (true){
c.clear();
synchronized (c) {
c.println("To continue adding logins, press C. To exit the program press ESC.");
c.println(pass[i][0] + " " + pass[i][1] + " " + pass[i][2]);
}
if (c.isKeyDown(KeyEvent.VK_C)){
break;
}
else if (c.isKeyDown(KeyEvent.VK_ESCAPE)){
fileWriter();
pass();
}
Thread.sleep(10);
}
}
}
Any help is greatly appreciated!! Thanks!
The main reason is because of this:
for (int j = 1; j <= pass.length; j++) {
pass[j][0] = freader.nextLine();
pass[j][1] = freader.nextLine();
pass[j][2] = freader.nextLine();
}
An array starts from 0. By making j = 1, you are starting on the second array in the group, you need to start with 0 and read up to but not including the array length.
I currently have a database access class to pull the data from my list listed like so:
Pique:CBPique.png:41:22:55:91
Ronaldo:STRonaldo.png:89:85:92:91
...
The class is as follows:
class DatabaseAccess {
static DatabaseAccess dataAccessor;
static DatabaseAccess getInstance(String dbPath) {
if (dataAccessor == null) {
dataAccessor = new DatabaseAccess(dbPath);
}
return dataAccessor;
}
private DatabaseAccess(String dbPath) {
dbLocation = dbPath;
}
List<FootballPlayer> getCards() {
return this.getData();
}
private List<FootballPlayer> getData() {
List<FootballPlayer> theData = new ArrayList<FootballPlayer>();
// create a Scanner and grab the data . . .
Scanner scanner = null;
String dataPath = dbLocation + File.separator + "text" + File.separator + "players.db";
String imagePath = dbLocation + File.separator + "images";
try {
scanner = new Scanner(new File(dataPath));
} catch (FileNotFoundException fnf) {
System.out.println(fnf.getMessage());
System.exit(0);
}
// scan players.db file line-by-line
scanner.useDelimiter("\n");
while (scanner.hasNext()) {
String line = scanner.next().trim();
// trim used to trim for new line
String[] bits = line.split(":");
String t = bits[0]; // title
String imgFileName = bits[1]; // image file name
int pa = Integer.parseInt(bits[2]); // pace
int sh = Integer.parseInt(bits[3]); // shooting
int dr = Integer.parseInt(bits[4]); // dribbling
int ph = Integer.parseInt(bits[5]); // physical
// create the image
ImageIcon img = new ImageIcon(imagePath + File.separator + imgFileName);
// Create the business object
FootballPlayer player = new FootballPlayer(t, img, pa, sh, dr, ph);
// add it to the list ... simple as ...
theData.add(player);
}
scanner.close();
return theData;
}
What I want to do is pull the data from this list and display it / use it within another class, for example pulling the image file names for use, or even displaying all the data in a list.
Been struggling with it and any help would be really appreciated.
This could be a way your Scanner may look like: It reads the file and saves line per line into an ArrayList.
ArrayList<String> singleParts = new ArrayList<String>();
try {
int index = 0;
Scanner scanner = new Scanner( new File("files/"+filename+".txt") );
while ( scanner.hasNextLine() ) {
String actualLine = scanner.nextLine();
singleParts.add(actualLine);
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(Throwable te) {
te.printStackTrace();
}
After this, you could iterate through your ArrayList line per line, char per char. To make things easier, you could use your ':' as a seperator.
Example first line, Name:
String name = "";
boolean saved = false;
for(int line = 0; line < singleParts.size(); line++) {
for(int char = 0; char < singleParts.get(line).length(); char++) {
if(char<singleParts.get(line).indexOf(':') {
name += singleParts.get(line).charAt(char);
}
}
}
To get the rest, you have a lot of possibilities. For example, cut away the already used chars and reuse the loop similar to this one.
Does your Player object have attributes/properties that are unique, such as name or ID?
Since you already have the Player object containing all the properties you need, why not put it in a HashMap instead of Arraylist, considering if you have a key to identify the specific Player?
FootballPlayer player = new FootballPlayer(t, img, pa, sh, dr, ph);
yourKey = t // an identifier to you player, in this case i used t for example
playersMap.put(t,player);
This way you can easily retrieve your Player by using
Player myPlayer = playersMap.get(yourKey)
// you can then get the properties of the Player
myPlayer.getImg();
myPlayer.getPa();
Hope this helps