Java BufferedFileReader skips first line - java

I'm trying to use the BufferedFileReader to read a Document with saved Information. It's working good, but it always skips the first line of the code. Is it because I'm calling readLine() in the for loop? If so how could I change it?
private void createViewUser() {
String[] stringFirstName = new String[10];
String[] stringName = new String[10];
String[] stringAge= new String[10];
try {
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
for (int i = 0; br.readLine() != null; i++) {
stringFirstName[i] = br.readLine();
stringName[i] = br.readLine();
stringAge[i] = br.readLine();
firstname[i] = new JTextField();
firstname[i].setBounds(100, 100 + 50 * i, 100, 30);
view.add(firstname[i]);
name[i] = new JTextField();
name[i].setBounds(200, 100 + 50 * i, 100, 30);
view.add(name[i]);
age[i] = new JTextField();
age[i].setBounds(300, 100 + 50 * i, 100, 30);
view.add(age[i]);
firstname[i].setText(stringFirstName[i]);
name[i].setText(stringName[i]);
age[i].setText(stringAge[i]);
}
fr.close();
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}

Exactly, each time before going into the for loop your program reads a line and checks if it is not null.
More you will also skip a line because of this condition. (not sure if it's desired or not)
You kinda got the answer yourself ;)

you're reading first line in the for loop:
for (int i = 0; br.readLine() /* HERE*/ != null; i++) {
You could do something like this:
String line = br.readLine();
for(int i = 0; line != null ; i++){
stringFirstName[i] = line;
line = br.readLine();
}

Hello you can init String var to fix it:
String line = br.readLine();
for (int i = 0; line != null; i++) {
stringFirstName[i] = line;
stringName[i] = br.readLine();
stringAge[i] = br.readLine();
It's doesn't work because it's load first line on for loop verification for (int i = 0; br.readLine() != null; i++) {
Good luck.

Your question involves several steps, but the most important issue for your purposes is how to efficiently and safely read data held in a text file when the data is presented in groups of three lines, something like:
first_name_1
last_name_1
age_1
first_name_2
last_name_2
age_2
first_name_3
last_name_3
age_3
first_name_4
last_name_4
age_4
where of course the names are replaced with real names, and likewise the age_? is replaced with a real number.
If you're going to go the BufferedReader route, I think that the safest thing to do is get all three Strings in each grouping within the while loop's boolean condition, something like:
BufferedReader reader = new BufferedReader(....);
// declare empty Strings first
String firstName = "";
String lastName = "";
String ageString = ""; // need to get age *first* as a String
while ((firstName = reader.readLine()) != null // get all 3 Strings here
&& (lastName = reader.readLine()) != null
&& (ageString = reader.readLine()) != null) { // boolean condition ends here
int age = Integer.parseInt(ageString.trim()); // NumberFormatException risk here
// ....
}
This way, if any of the Strings in the text file are missing, the whole while loop ends, and bad data is not obtained.
Other recommendations, create a plain-old Java object to hold your Person data, the names and the age, a class with 3 fields, 2 that are Strings for the names, and one int field for the age. Give it a decent constructor, getter methods.... For example:
public class Person {
private String firstName;
private String lastName;
private int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
#Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + "]";
}
}
This way, the while loop above could be used to simply create Person objects:
List<Person> persons = new ArrayList<>(); // an ArrayList of Person to hold the data
while ((firstName = reader.readLine()) != null // get all 3 Strings here
&& (lastName = reader.readLine()) != null
&& (ageString = reader.readLine()) != null) { // the while loop ends here
int age = Integer.parseInt(ageString.trim());
Person person = new Person(firstName, lastName, age); // create a new Person object
persons.add(person); // put it into the arraylist
}
OK, how about displaying this information into a JTable -- that's easy.
Create a DefaultTableModel with the correct column names:
private static final String[] COL_NAMES = { "First Name", "Last Name", "Age" };
private DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0);
and then create a JTable with this model:
private JTable table = new JTable(model);
Then iterate through the ArrayList<Person> and fill our model with data:
for (Person person : personList) {
Vector<Object> rowData = new Vector<>();
rowData.add(person.getFirstName());
rowData.add(person.getLastName());
rowData.add(person.getAge());
model.addRow(rowData);
}
and the JTable is created and filled with data, just like that.
OK, assuming a data file called PersonData.txt that is located in the same directory as our class files, like so:
And assuming that this file holds our data like so:
John
Smith
21
Fred
Flinstone
53
Barny
Rubble
52
Mary
Contrary
22
Bo
Peep
12
Donald
Trump
75
Donald
Duck
40
Mickey
Mouse
45
Minnie
Mouse
41
Ebenezer
Scrooge
80
Bob
Cratchit
33
Ralph
Kramden
55
Alice
Kramden
48
Ed
Norton
54
Then using our Person.java class, we can create a GUI to hold and display our data like so:
import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
#SuppressWarnings("serial")
public class PersonDisplay extends JPanel {
private static final String[] COL_NAMES = { "First Name", "Last Name", "Age" };
private static final String PERSON_DATA_PATH = "PersonData.txt";
private DefaultTableModel model = new DefaultTableModel(COL_NAMES, 0);
private JTable table = new JTable(model);
public PersonDisplay(List<Person> personList) {
for (Person person : personList) {
Vector<Object> rowData = new Vector<>();
rowData.add(person.getFirstName());
rowData.add(person.getLastName());
rowData.add(person.getAge());
model.addRow(rowData);
}
setLayout(new BorderLayout());
add(new JScrollPane(table));
}
private static void createAndShowGui(List<Person> personList) {
PersonDisplay mainPanel = new PersonDisplay(personList);
JFrame frame = new JFrame("Person Display");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static List<Person> readInPersons(InputStream is) throws IOException {
List<Person> persons = new ArrayList<>();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String firstName = "";
String lastName = "";
String ageString = "";
while ((firstName = reader.readLine()) != null
&& (lastName = reader.readLine()) != null
&& (ageString = reader.readLine()) != null) {
int age = Integer.parseInt(ageString.trim());
Person person = new Person(firstName, lastName, age);
persons.add(person);
}
return persons;
}
public static void main(String[] args) {
try {
InputStream inputStream = PersonDisplay.class.getResourceAsStream(PERSON_DATA_PATH);
List<Person> personList = readInPersons(inputStream);
SwingUtilities.invokeLater(() -> createAndShowGui(personList));
} catch (IOException e) {
e.printStackTrace();
}
}
}
and when displayed, it would look like:

Related

Is there a way to collect data in multiple excel files?

there are 12 excel files that contain different products sales data, I try to sum up each month and entire year's sales using java but I can't add up sales for the whole year. Is there a way to do that? Thanks for your help.
public class Main {
public static void listOfSales(String fileName,String month){
List<PriceList> list = readsListFroExcel(fileName);
int sumOfInYearSale = 0;
int sumOfInOnlineSale =0;
int sumOfTotalMonthlySale = 0;
for (PriceList x : list){
sumOfInYearSale = sumOfInYearSale + x.getTotalPhysicalSale();
sumOfInOnlineSale = sumOfInYearSale + x.getTotalOnlineSale();
}
System.out.println(month +" Physical Sales : "+sumOfInYearSale);
System.out.println(month+ " Online Sales :" +sumOfInOnlineSale);
}
private static List<PriceList> readsListFroExcel(String fileName) {
List<PriceList> list = new ArrayList<>();
Path pathTofile = Paths.get(fileName);
try (BufferedReader br = Files.newBufferedReader(pathTofile)){
String headerLine = br.readLine();
String line = br.readLine();
while (line!=null){
String[] attributes = line.split(",");
PriceList listOfPrice = createList(attributes);
list.add(listOfPrice);
line = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
}

NoSuchElement Exception in Thread in TextFile Program

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.

Read txt file and return an array of objects that has multiple fields

I have a text file, in which each line is an Movie instance, and Movie object's fields are separated by a tab.
I need to read it and return an array of object (each line), that has multiple fields. I don't know how to make the array of Movie object ( i.e. Movie[]) and return it.
Sample text file I'm reading:
id title price
001 titanic 2
002 lady bird 3
The following is what I've got so far.
public class Loader {
//private String csvFile;
private static final Resource tsvResource = new ClassPathXmlApplicationContext().getResource("classpath:movies.txt");
private static InputStream movieIS = null;
public Loader() {
try {
movieIS = tsvResource.getInputStream();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Movie[] loadMovies() {
BufferedReader br = null;
String line = "";
String[] tempArray = new String[100];
int id;
String title;
String rating;
String synopsis;
String genre;
String director;
String[] actors;
int price;
int runtime;
int index = 0;
try {
br = new BufferedReader(new InputStreamReader(movieIS));
while ((line = br.readLine()) != null) {
index++;
String[] data = line.split("\\t");
id = Integer.parseInt(data[0]);
title = data[1];
rating = data[2];
synopsis = data[3];
genre = data[4];
director = data[5];
actors = data[6].split(";");
price = Integer.parseInt(data[7]);
runtime = Integer.parseInt(data[8]);
}
String[] lines = new String[index];
for (int i = 0; i < index; i++) {
lines[i] = br.readLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return;
}
}
You've almost got this. You can create the Movie object from the fields you've extracted (like title, rating , synopsis, actors etc.) and add them to your array.
Also I'd suggest you to use ArrayList instead of array for your movies (unless you're absolute sure of the number of movies you'd have)
Your loadMovies method would look like this:
public static List<Movie> loadMovies() {
// Initialize your movie list
List<Movie> movieList = new ArrayList<>();
String line = "", title, rating, synopsis, genre, director;
int id, price, runtime, index = 0;
String[] actors;
try (BufferedReader br = new BufferedReader(new InputStreamReader(movieIS))) {
while ((line = br.readLine()) != null) {
index++;
String[] data = line.split("\\t");
id = Integer.parseInt(data[0]);
title = data[1];
rating = data[2];
synopsis = data[3];
genre = data[4];
director = data[5];
actors = data[6].split(";");
price = Integer.parseInt(data[7]);
runtime = Integer.parseInt(data[8]);
// Create your Movie object here,
// note that I'm using constructor here,
// You can also use setters for optional fields as well
Movie movie = new Movie(id, title, rating, synopsis, genre, director, actors, price, runtime);
movieList.add(movie);
}
String[] lines = new String[index];
for (int i = 0; i < index; i++) {
lines[i] = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
//return movieList
return movieList;
}
Note that I've combined the variable declarations and try-catch blocks as well in your original code.
Do something like
ArrayList <> al = new ArrayList<Movie>();
int index = 0;
try{
br=new BufferedReader(new InputStreamReader(movieIS));
while((line=br.readLine())!=null){
index++;
String[] data=line.split("\\t");
id =Integer.parseInt(data[0]);
title=data[1];
rating=data[2];
synopsis=data[3];
genre=data[4];
director=data[5];
actors=data[6].split(";");
price= Integer.parseInt(data[7]);
runtime=Integer.parseInt(data[8]);
Movie mv = new Movie();
// load into mv
al.add(mv);
}
}
and return at the end like this:
return al.toArray();

java read text file column headers in random order

I recieve a file each day that:
is stab delimited
has 5 or more columns
has 3 common columns - lastName, firstName, address
Problem: the column order of the file changes regularly
Goal: print column data for lastName, firstName, address regardless of column order
I have been using the following code and manually changing the datavalues to match the columns.
testfile1.txt
1st day file format
ID lastName address phone firstName
45 Gates 111 some lane 777-888-9999 Bill
2nd day file format
address ID phone firstName lastName
111 some lane 81 444-555-1111 John Doe
-
import java.io.BufferedReader;
import java.io.FileReader;
public class test2 {
public static void main(String args[]) throws Exception {
String dataFileName = "C:/testfiles/testfile1.txt";
String line;
int lineNumber = 0;
BufferedReader bReader = new BufferedReader(new FileReader(dataFileName));
bReader.readLine();
while ((line = bReader.readLine()) != null) {
lineNumber++;
String datavalue[] = line.split("\t");
String lastName = datavalue[1];
String firstName = datavalue[5];
String address = datavalue[3];
System.out.println(lastName + "'" + firstName + "," + address);
}
}
}
This is a first approach. I would try it somehow like this:
int colLastName, colFirstName, colAddress;
line = bReader.readLine();
String columnOrder []= line.split("\t");
for (int i=0; i< columnOrder.length; i++){
if (columnOrder[i].equals("lastName")){
colLastName = i;
}
else if (columnOrder[i].equals("firstName"){
colFirstName = i;
}
else if (columnOrder[i].equals("address"){
colAddress = i;
}
}
while ((line = bReader.readLine()) != null) {
lineNumber++;
String datavalue[] = line.split("\t");
String lastName = datavalue[colLastName];
String firstName = datavalue[colFirstName];
String address = datavalue[colAddress];
System.out.println(lastName + "'" + firstName + "," + address);
}
I think you can try something like below -
import java.io.BufferedReader;
import java.io.FileReader;
public class test2 {
public static void main(String args[]) throws Exception {
String dataFileName = "C:/testfiles/testfile1.txt";
String line;
boolean isFirstColumn = true;
BufferedReader bReader = new BufferedReader(new FileReader(dataFileName));
int[] order_Fname_Lname_Address = new int[3];
while ((line = bReader.readLine()) != null) {
String datavalue[] = line.split("\t");
if(isFirstColumn) {
for (int i = 0; i < datavalue.length; i++) {
switch (datavalue[i]) {
case "firstName":
order_Fname_Lname_Address[0] = i;
break;
case "lastName":
order_Fname_Lname_Address[1] = i;
break;
case "address":
order_Fname_Lname_Address[2] = i;
break;
}
}
isFirstColumn = false;
continue;
}
String firstName = datavalue[order_Fname_Lname_Address[0]];
String lastName = datavalue[order_Fname_Lname_Address[1]];
String address = datavalue[order_Fname_Lname_Address[2]];
System.out.println(lastName + " " + firstName + "," + address);
}
bReader.close();
}
}

How to read from a text-file.

I would like to know how can I check for a specific string on a line of a text file, save it in an array, and then move on to the next line of that text file.
For e.g.:
(what he is/ year edition/name/age/profession/number)
competitor 2014 joseph 21 student 20232341
competitor 2013 michael 23 engineer 23425123
As output, it would give me this:
Song Festival'2014
here are the competitors:
Joseph, student of 21 years - 20232341
Song Festival'2013
are the competitors
Michael, engineer of 23 years - 23425123
edit: java language
For this you would use a BufferedReader, you can format things in the text file using the tab (indent) which would be read from the BufferedReader as '\t' I'll write an example for you in a moment.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class StackoverflowExample {
private static final int INFORMATION_CAP = 100;
private static String[][] INFORMATION = new String[INFORMATION_CAP][INFORMATION_CAP];
public StackoverflowExample() {
String currentLine;
String[] textData;
int lineID = 0;
boolean endOfFile = false;
try {
BufferedReader reader = new BufferedReader(new FileReader("textfile.txt"));
currentLine = reader.readLine();
while(!endOfFile && currentLine != null) {
currentLine = currentLine.trim();
textData = currentLine.split("\\t");
String userType = textData[0];
String year = textData[1];
String name = textData[2];
String age = textData[3];
String profession = textData[4];
String number = textData[5];
INFORMATION[lineID] = new String[] { userType, year, name, age, profession, number };
lineID++;
currentLine = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new StackoverflowExample();
for(int i = 0; i < INFORMATION.length; i++) {
System.out.println("Type: " + INFORMATION[i][0] +
"year: " + INFORMATION[i][1] +
"name: " + INFORMATION[i][2] +
"age: " + INFORMATION[i][3] +
"profession: " + INFORMATION[i][4] +
"number: " + INFORMATION[i][5]);
}
}
}
Create a text file called "textfile.txt" in your projects main directory, and format it like this
type(tab)year(tab)name(tab)age(tab)profession(tab)number(newline)

Categories

Resources