error while getting data from file to array - java

I'm trying to get saved data in a text file to an array to use it in my code and then search this array for a string submitted from the user from the GUI , but for some reason I print out the data in the array it is all null. here's the code !!
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class IO {
File f = new File("DB.txt");
PrintWriter write;
Scanner input;
String[][] data;
String nameToSearch;
// search constructor
public IO(String name) {
super();
nameToSearch = name;
try {
input = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("File not found please restart the program");
}
data = new String[linesCounter()][2];
int i = 0;
while (input.hasNext()) {
data[i][0] = input.nextLine();
data[i][1] = input.nextLine();
i++;
}
}
public IO(String name, String number) {
try {
write = new PrintWriter(new FileWriter(f, true));
} catch (IOException e) {
System.out.println("Error");
}
write.println(name);
write.println(number);
write.close();
}
int linesCounter() {
try {
input = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("File not found please restart the program");
}
int counter = 0;
while (input.hasNext()) {
input.nextLine();
counter++;
}
return counter / 2;
}
int contactFinder() {
int i = 0;
while (input.hasNext()) {
if (data[i][0].equalsIgnoreCase(nameToSearch))
return i;
i++;
}
return -1;
}
String nameGetter() {
return data[contactFinder()][0];
}
String numGetter() {
return data[contactFinder()][1];
}
}

It looks like you read all the lines in from the file to count how many lines there are, and then when you go to read the data, you're starting from where you left off, which would be the end of the file.
It's also worth noting that you can use commons-io FileUtils to easily read all the lines from a file.
For example:
List<String> lines = FileUtils.readLines(f);
String[][] data = new String[lines.length][2];
for (int i = 0; i < lines.size(); i++) {
data[i][i % 2] = lines.get(i);
}
If you also don't want to use a (very useful) third party library, you could load up the data pretty simply with:
List<String> lines = new ArrayList<String>();
Scanner input = new Scanner(f);
while (input.hasNextLine()) {
lines.add(input.nextLine());
}
input.close();
Then go into the array population.

I would advice you to use RandomAccessFile. This has methods such as readLine() to read the line and seek(long pos) to set the file read pointer. You may use seek(0L) to restart the reading of the file.

Related

Why my Java program works perfectly in windows but it's a disaster in linux?

I wrote a program that reads a text file, deletes the requested string and rewrites it without the string. This program takes three arguments from the terminal: 1) the input file 2) the string 3) the output file.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
class wordfilter {
public static void main(String[] args) {
Scanner scanner = new Scanner("");
Scanner conteggio = new Scanner("");
int numel = 0;
File file = new File(args[0]); // Argomento 0: il file
try {
conteggio = new Scanner(file);
}
catch (FileNotFoundException e) {
System.out.println("File non trovato");
}
while (conteggio.hasNext()) {
numel++;
conteggio.next();
}
conteggio.close();
String[] lettura = new String[numel];
int i = 0;
try {
scanner = new Scanner(file);
}
catch (FileNotFoundException e) {
System.out.println("File non trovato");
}
while (scanner.hasNextLine()) {
lettura[i] = scanner.next();
i++;
}
System.out.println("Contarighe -> " + numel);
for (i = 0; i < lettura.length; i++) {
System.out.println("Elemento " + i + " - > " + lettura[i]);
}
scanner.close();
String escludi = args[1]; // Argomento 1: il filtro
String[] filtrato = rimuovi(escludi, lettura);
if (args.length == 3) stampaSuFile(filtrato, args[2]);
}
public static String[] rimuovi(String esclusione, String[] input) {
String[] nuovoV;
String escludi = esclusione;
int dim = 0;
for (int i = 0; i < input.length; i++) {
if (!input[i].equals(escludi))
dim++;
}
nuovoV = new String[dim];
int j = 0;
for (int i = 0; i < input.length; i++) {
if (!input[i].equals(escludi)) {
nuovoV[j] = input[i];
j++;
}
;
}
return nuovoV;
}
public static void stampaSuFile(String[] out, String path) {
String closingstring = "";
File destinazione = new File(path);
try {
destinazione.createNewFile();
} catch (IOException e) {
System.out.println("Errore creazione file");
}
try {
FileWriter writer = new FileWriter(destinazione);
for (int i = 0; i < out.length; i++)
writer.write(out[i] + (i == (out.length-1) ? closingstring : " "));
writer.close();
System.out.println("Scrittura eseguita correttamente");
} catch (IOException e) {
System.out.println("Errore scrittura file");
}
}
}
On Windows no problem, it works perfectly.
On Linux instead when i write something like java wordfilter in.txt word out.txt
I get
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1478)
at wordfilter.main(wordfilter.java:42)
What's the problem? It's because of some difference on linux?
You're mixing line and token based functions, :hasNextLine() and next(). If the input ends with a line feed (typical on Linux) hasNextLine returns true at the end of the file, but there is no next "item".
while (scanner.hasNextLine()) {
lettura[i] = scanner.next();
i++;
}
You should use either hasNext with next, or hasNextLine with nextLine, mixing them is confusing.
while (scanner.hasNext()) {
lettura[i] = scanner.next();
i++;
}
The input file ends in a newline on Linux. Therefore, there's another line, but it's empty. If you remove the final newline from the input, the program will start working normally.
Or, import the exception
import java.util.NoSuchElementException;
and ignore it int the code
while (scanner.hasNextLine()) {
System.out.println("" + i);
try {
lettura[i] = scanner.next();
} catch (NoSuchElementException e) {}
i++;
}

Scanner for input file and storing data objects from input file in array

Basically, I had to create a scanner for a given file and read through the file (the name is input through the terminal by the user) once counting the number of lines in the file. Then after, I had to create an array of objects from the file, of the correct size (where the num of lines comes in). Then I had to create another scanner for the file and read through it again, storing it in the array I created. And lastly, had to return the array in the method.
My problem is I cannot seem to get the second scanner to actually store the file objects in the array.
I've tried using .nextLine inside a for loop that also calls the array, but it doesn't seem to be working.
public static Data[] getData(String filename) {
Scanner input = new Scanner(new File(filename));
int count = 0;
while (input.hasNextLine()) {
input.nextLine();
count++;
}
System.out.println(count);
Data[] data = new Data[count];
Scanner input1 = new Scanner(new File(filename));
while (input1.hasNextLine()) {
for (int i = 0; i < count; i++) {
System.out.println(data[i].nextLine);
}
}
return data;
}
I expect the output to successfully read the input file so that it can be accessed by other methods that I have created (not shown).
You should definitely use an IDE if you don't have one, try intellij... There you have autocompletion and syntax checking and much more.
It is not clear what you want to do in your for loop, because there are several mistakes, for example the readline() function works only with the scanner objekt, so you can do input.nextline() or input1.nextline()`...
so I just show you, how you can get the Data from a file with Scanner:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Readfile {
public static void getData(String filename) throws FileNotFoundException {
ArrayList<String> test = new ArrayList<>(); //arraylist to store the data
Scanner inputSc = new Scanner(new File(filename)); //scanner of the file
while (inputSc.hasNextLine()) {
String str = inputSc.nextLine();
System.out.println(str); //print the line which was read from the file
test.add(str); //adds the line to the arraylist
//for you it would be something like data[i] = str; and i is a counter
}
inputSc.close();
}
public static void main(String[] args) {
try {
getData("/home/user/documents/bla.txt"); //path to file
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
You don't need to read thru the file twice - just use an ArrayList to hold the data that's coming in from the file, like this, and then return Data[] at the end:
public static Data[] getData(String filename) {
List<Data> result = new ArrayList<>();
try (Scanner input = new Scanner(new File(filename))){
while (input.hasNextLine()) {
Data data = new Data(input.nextLine());
result.add(data);
}
}
return result.toArray(new Data[0]);
}
Not clear what Data.class do you mean, if you switch it to String, the problem obviously would be in this line
System.out.println(data[i].nextLine);
if you want to assign and print simultaneously write this
for (int i = 0; i < count; i++) {
data[i] = input1.next();
System.out.println(data[i]);
}
and dont forget to close your Scanners, better use try-with-resources.
If your Data is your custom class you'd better learn about Serialization-Deserialization
Or use some ObjectMapper-s(Jackson, for example) to store your class instances and restore them.
Your way of opening the file just to count the lines and then again looping through its lines to store them in the array is not that efficient, but it could be just a school assignment.
Try this:
public static Data[] getData(String filename) {
Scanner input = null;
try {
input = new Scanner(new File(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
int count = 0;
while (input.hasNextLine()) {
input.nextLine();
count++;
}
input.close();
System.out.println(count);
Data[] data = new Data[count];
try {
input = new Scanner(new File(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
for (int i = 0; i < count; i++) {
Data d = new Data(input.nextLine(), 0, 0);
data[i] = d;
System.out.println(data[i].name);
}
input.close();
return data;
}
After the 1st loop you must close the Scanner and reopen it so to start all over from the first line of the file.

Writing an object array to csv file in java

I am trying to take an initial CSV file, pass it through a class that checks another file if it has an A or a D to then adds or deletes the associative entry to an array object.
example of pokemon.csv:
1, Bulbasaur
2, Ivysaur
3, venasaur
example of changeList.csv:
A, Charizard
A, Suirtle
D, 2
That being said, I am having a lot of trouble getting the content of my new array to a new CSV file. I have checked to see whether or not my array and class files are working properly. I have been trying and failing to take the final contents of "pokedex1" object array into the new CSV file.
Main File
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class PokedexManager {
public static void printArray(String[] array) {
System.out.print("Contents of array: ");
for(int i = 0; i < array.length; i++) {
if(i == array.length - 1) {
System.out.print(array[i]);
}else {
System.out.print(array[i] + ",");
}
}
System.out.println();
}
public static void main(String[] args) {
try {
//output for pokedex1 using PokemonNoGaps class
PokemonNoGaps pokedex1 = new PokemonNoGaps();
//initializes scanner to read from csv file
String pokedexFilename = "pokedex.csv";
File pokedexFile = new File(pokedexFilename);
Scanner pokescanner = new Scanner(pokedexFile);
//reads csv file, parses it into an array, and then adds new pokemon objects to Pokemon class
while(pokescanner.hasNextLine()) {
String pokeLine = pokescanner.nextLine();
String[] pokemonStringArray = pokeLine.split(", ");
int id = Integer.parseInt(pokemonStringArray[0]);
String name = pokemonStringArray[1];
Pokemon apokemon = new Pokemon(id, name);
pokedex1.add(apokemon);
}
//opens changeList.csv file to add or delete entries from Pokemon class
String changeListfilename = "changeList.csv";
File changeListFile = new File(changeListfilename);
Scanner changeScanner = new Scanner(changeListFile);
//loads text from csv file to be parsed to PokemonNoGaps class
while(changeScanner.hasNextLine()) {
String changeLine = changeScanner.nextLine();
String[] changeStringArray = changeLine.split(", ");
String action = changeStringArray[0];
String nameOrId = changeStringArray[1];
//if changList.csv file line has an "A" in the first spot add this entry to somePokemon
if(action.equals("A")) {
int newId = pokedex1.getNewId();
String name = nameOrId;
Pokemon somePokemon = new Pokemon(newId, name);
pokedex1.add(somePokemon);
}
//if it has a "D" then send it to PokemonNoGaps class to delete the entry from the array
else { //"D"
int someId = Integer.parseInt(nameOrId);
pokedex1.deleteById(someId);
}
//tests the action being taken and the update to the array
//System.out.println(action + "\t" + nameOrId + "\n");
System.out.println(pokedex1);
//*(supposedly)* prints the resulting contents of the array to a new csv file
String[] pokemonList = changeStringArray;
try {
String outputFile1 = "pokedex1.csv";
FileWriter writer1 = new FileWriter(outputFile1);
writer1.write(String.valueOf(pokemonList));
} catch (IOException e) {
System.out.println("\nError writing to Pokedex1.csv!");
e.printStackTrace();
}
}
//tests final contents of array after being passed through PokemonNoGaps class
//System.out.println(pokedex1);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
PokemonNoGaps class file:
public class PokemonNoGaps implements ChangePokedex {
private Pokemon[] pokedex = new Pokemon[1];
private int numElements = 0;
private static int id = 0;
// add, delete, search
#Override
public void add(Pokemon apokemon) {
// if you have space
this.pokedex[this.numElements] = apokemon;
this.numElements++;
// if you don't have space
if(this.numElements == pokedex.length) {
Pokemon[] newPokedex = new Pokemon[ this.numElements * 2]; // create new array
for(int i = 0; i < pokedex.length; i++) { // transfer all elements from array into bigger array
newPokedex[i] = pokedex[i];
}
this.pokedex = newPokedex;
}
this.id++;
}
public int getNewId() {
return this.id + 1;
}
#Override
public void deleteById(int id) {
for(int i = 0; i < numElements; i++) {
if(pokedex[i].getId() == id) {
for(int j = i+1; j < pokedex.length; j++) {
pokedex[j-1] = pokedex[j];
}
numElements--;
pokedex[numElements] = null;
}
}
}
public Pokemon getFirstElement() {
return pokedex[0];
}
public int getNumElements() {
return numElements;
}
public String toString() {
String result = "";
for(int i = 0; i < this.numElements; i++) {
result += this.pokedex[i].toString() + "\n";
}
return result;
}
}
Excpeted output:
1, Bulbasaur
3, Venasaur
4, Charizard
5, Squirtle
Am i using the wrong file writer? Am I calling the file writer at the wrong time or incorrectly? In other words, I do not know why my output file is empty and not being loaded with the contents of my array. Can anybody help me out?
I spotted a few issues whilst running this. As mentioned in previous answer you want to set file append to true in the section of code that writes to the new pokedx1.csv
try {
String outputFile1 = "pokedex1.csv";
FileWriter fileWriter = new FileWriter(prefix+outputFile1, true);
BufferedWriter bw = new BufferedWriter(fileWriter);
for(String pokemon : pokedex1.toString().split("\n")) {
System.out.println(pokemon);
bw.write(pokemon);
}
bw.flush();
bw.close();
} catch (IOException e) {
System.out.println("\nError writing to Pokedex1.csv!");
e.printStackTrace();
}
I opted to use buffered reader for the solution. Another issue I found is that your reading pokedex.csv but the file is named pokemon.csv.
String pokedexFilename = "pokemon.csv";
I made the above change to fix this issue.
On a side note I noticed that you create several scanners to read the two files. With these types of resources its good practice to call the close method once you have finished using them; as shown below.
Scanner pokescanner = new Scanner(pokedexFile);
// Use scanner code here
// Once finished with scanner
pokescanner.close();
String outputFile1 = "pokedex1.csv";
FileWriter writer1 = new FileWriter(outputFile1);
appears to be within your while loop so a new file will be created every time.
Either use the FileWriter(File file, boolean append) constructor or create before the loop

How to select a random word from a txt file?

I have a method that needs to select a random word from a txt file, but it only works some of the time.
The content of the file is as follows:
Broccoli
Tomato
Kiwi
Kale
Tomatillo
My code:
import java.util.Random;
import java.util.Scanner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public String getRandomItem(){
Scanner fileIn = null;
String temp = "";
int r = randomGenerator.nextInt(5) + 1;
byte i = 0;
try {
fileIn = new Scanner(new FileInputStream("bundles.txt"));
} catch (FileNotFoundException e) {
System.out.println("File not found.");
System.exit(0);
}
while(i <= 5){
temp = fileIn.nextLine();
if(i == r){
break;
}
i++;
}
fileIn.close();
return temp;
}
Could someone please tell me where I am going wrong?
I would use Files.readAllLines(Path) to read all the lines once, and then get a single random word from that. Something like,
private static List<String> lines = null;
static {
try {
lines = Files.readAllLines(new File("bundles.txt").toPath());
} catch (IOException e) {
e.printStackTrace();
}
}
private Random rand = new Random();
public String getRandomItem() {
return lines.get(rand.nextInt(lines.size()));
}

Random selected strings

I have a text file and i am trying to convert every line into an ArrayList. Then i have to take a random line from this text.file and display it on new JOptionPane.
I am trying to implement it in the for-loop but it always appears only the first line from my text.file. Thank you very much and here is my code.
public void actionPerformed(ActionEvent e) {
ArrayList<String> allQuestions = new ArrayList<String>();
ArrayList<String> allRandomSelectedQuestions = new ArrayList<String>();
File file = new File("C:/Users/User/Documents/NetBeansProjects/SummerExamProject/src/Questions2.txt");
int numberOfRandomQuestions = 16;
try {
//Read line by line from the file
Scanner scan = new Scanner(file);
while (scan.hasNextLine()) {
String line = scan.nextLine();
// System.out.println(line);
JOptionPane.showMessageDialog(null, line.replace("/", "\n"));
scan.close();
allQuestions.add(line);
}
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
for(int i = 0; i < numberOfRandomQuestions; i++){
Random randNum = new Random();
int randQuestionIndex = randNum.nextInt(numberOfRandomQuestions);
String randomQuestion = allQuestions.get(randQuestionIndex);
allRandomSelectedQuestions.add(randomQuestion);
}
}
This line...
scan.close();
Is inside your while loop, so it closes the file after reading a line the first time it goes through the loop.
Moving it to after the loop (i.e. after the close culry-brace) ought to fix it.
The problem is this: scan.close();. You are closing your scanner in the same loop you are using for reading. Moving it outside the loop body should solve the problem.
Call close method after the while loop. What is happening that, you close after the first line. so the while loop stops after only one time.
while (scan.hasNextLine()) {
String line = scan.nextLine();
//System.out.println(line);
JOptionPane.showMessageDialog(null, line.replace("/", "\n"));
allQuestions.add(line);
}
scan.close();
Try this. Hope it helps.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class StackTest {
public static void main(String[] args) {
actionPerformed();
}
public static void actionPerformed() {
ArrayList<String> allQuestions = new ArrayList<String>();
File file = new File("D:/me/test.txt");
int numberOfRandomQuestions = 10;
try {
// Read line by line from the file
Scanner scan = new Scanner(file);
while (scan.hasNextLine()) {
String line = scan.nextLine();
allQuestions.add(line);
}
scan.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
for (int i = 0; i < numberOfRandomQuestions; i++) {
Random randNum = new Random();
int randQuestionIndex = randNum.nextInt(numberOfRandomQuestions);
System.out.println();
String randomQuestion = allQuestions.get(randQuestionIndex);
JOptionPane.showMessageDialog(null, randomQuestion.replace("/", "\n"));
}
}
}

Categories

Resources