I have a problem in file handling in java - java

any help will be appreciated.
print some details about fines on it, but the code is not giving me an output.
my code is :

class BookLib{
String userName ;
String bookName;
int noOfDays;
int fine;
#Override
public String toString() {
return "BookLib{" +
"userName='" + userName + '\'' +
", bookName='" + bookName + '\'' +
", noOfDays=" + noOfDays + '}';
}
}
class Library{
List<BookLib> books = new ArrayList<>();
void readDetails() throws IOException{
FileReader fr = new FileReader("fineDetails.txt");
BufferedReader br = new BufferedReader(fr);
String thisLine;
List<String> lines = new ArrayList<>();
while ((thisLine = br.readLine()) != null) {
lines.add(thisLine);
}
for(String readLine: lines){
StringTokenizer stringTokenizer = new StringTokenizer(readLine, ",");
BookLib tempBook = new BookLib();
tempBook.userName = stringTokenizer.nextToken().trim();
tempBook.bookName = stringTokenizer.nextToken().trim();
tempBook.noOfDays = Integer.parseInt(stringTokenizer.nextToken().trim());
System.out.println("BookLib = " + tempBook);
books.add(tempBook)
}
br.close();
fr.close();
}
I Hope, Above code, is helping you for handling NumberFormatException and future ArrayIndexOutOfBoundException handling. you may also use try-catch {} for handling these errors.

The problem is that you can't parse the String "25 " to an Integer because of the whitespace.
You can remove the whitespace using the trim method of String like this:
//...
book[i].userName = stringTokenizer.nextToken();
book[i].bookName = stringTokenizer.nextToken();
book[i].noOfDays = Integer.parseInt(stringTokenizer.nextToken().trim()); // trim here
//...
I think there is another problem that didn't cause any errors yet, because the NumberFormatException occured earlier: You do close the readers br and fr in the for loop, but they will still be used there. You should move the lines br.close() and fr.close() down to the end of the method.

Related

Reading from csv adds whitespace that can't be removed Java

I am reading from a csv file of people, starting with their id, name, and date they joined the application. When reading the first row, the first index adds a whitespace to the string. I am unable to remove this whitespace, as I want to parse it to an integer.
File nameOfFile = fileName;
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
br = new BufferedReader(new FileReader(nameOfFile));
while ((line = br.readLine()) != null) {
String[] row = line.split(cvsSplitBy);
temp = row[0].trim();
temp.replaceAll("^\\s", "");
// temp.replaceAll(" ", "");
// String.format("%03d", temp);
System.out.println(temp.length() + " " + temp + " " + temp.charAt(0));
age = Integer.parseInt(temp);
name = row[1];
dateJoined = row[2];
}
} catch (FileNotFoundException | ArrayIndexOutOfBoundsException exception) {
System.out.println("File is not found, please try again.");
System.out.println(exception);
}
if (br != null) {
br.close(); //close buffered reader
}
My csv file:
4 John 10/10/2010
5 Charles 24/08/2010
6 Andrew 09/01/2011
The System.out.println(temp.length() + " " + temp + " " + temp.charAt(0)); prints this:
2 4
1 5 5
1 6 6
where this System.out.println(temp.length() + " " + temp + " " + temp.charAt(1)); prints out:
2 4 4
Don't reinvent the wheel. I would use the Univocity parser and then map.
More info at: https://www.univocity.com/pages/parsers-documentation
Something along this (did not test it);
CsvParserSettings settings = new CsvParserSettings();
CsvParser parser = new CsvParser(settings);
List<String[]> allRows = parser.parseAll(new FileReader(yourfile));
List<Person> persons = allRows.stream().map(p->new Person(p[0],p[1],p[2])).collect(Collectors.toList())
In the Person bean I would make specific setMethods, such as:
public void setAge(String age2parse){
try{
this.age = Integer.parse(age2parse.replaceAll("[^\\d.]",""))
}catch(Exception e){
}
}
public void setName(String name2parse){
this.name = name; // You could divide name here, if wanted.
}
public void setDate(String date2parse){
this.date = date2parse // I would parse it and store it as Date object.
}
Finnaly, a constructor in the bean;
public Person(String a, String n, String d){
setAge(a);
setName(n);
setDate(d);
}
To print:
persons.stream().forEachOrdered(p->System.out.println(p.getAge()+" "+p.getName()+" "+p.getDate()))
Note: There is even way to use BeanRowProcessors, which seem to fit well when you have more fields in the bean, so please, check the documentation on Univocity.

Handle Empty lines in Java

I am facing a problem in the following code. I am trying to run the program and it terminates when it hits empty space in my input. How else I should approach this.
try {
BufferedReader sc = new BufferedReader(new FileReader(text.txt);
ArrayList<String> name = new ArrayList<>();
ArrayList<String> id = new ArrayList<>();
ArrayList<String> place = new ArrayList<>();
ArrayList<String> details = new ArrayList<>();
String line = null;
while ((line = sc.readLine()) !=null) {
if (!line.trim().equals("")) {
System.out.println(line);
if (line.toLowerCase().contains("name")) {
name.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("id")) {
id.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("location")) {
place.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("details")) {
details.add(line.split("=")[1].trim());
}
}
}
PrintWriter pr = new PrintWriter(new File(text.csv));
pr.println("Name;Id;;Location;Details");
for (int i = 0; i < name.size(); i++) {
pr.println(name.get(i) + ";" + id.get(i) + ";" + place.get(i) + ";" + details.get(i));
}
pr.close();
sc.close();
} catch (Exception e) {
e.printStackTrace();
} }
My Input looks like
name = abc
id = 123
place = xyz
details = hsdyhuslkjaldhaadj
name = ert
id = 7872
place =
details = shahkjdhksdhsala
name = sfd
id = 4343
place = ksjks
Details = kljhaljs
when im trying to execute then above text my program terminates at place = "null" because of no value there.I need the output as an empty space created in place ="null" and print the rest as follows in a .csv file
If you process the location, line.split("=")[1] could result in an ArrayIndexOutOfBoundException and line.split("=")[1].trim() could result in a NullPointerException.
You can avoid this by testing your parsed result.
Instead of place.add(line.split("=")[1].trim());, do place.add(parseContentDefaultEmpty(line));, with:
private String parseContentDefaultEmpty(final String line) {
final String[] result = line.split("=");
if(result.length <= 1) {
return "";
}
final String content = line.split("=")[1];
return content != null ? content.trim() : "";
}
First there is a issue,your input file contains key as "place" but your are trying for word "location"
if (line.toLowerCase().contains("location")) { //this must be changed to place
place.add(line.split("=")[1].trim());
}
Modified the code snippet as below.check it
while ((line = sc.readLine()) != null) {
if (!line.trim().equals("")) {
System.out.println(line);
if (line.toLowerCase().contains("name")) {
name.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("id")) {
id.add(line.split("=")[1].trim());
}
if (line.toLowerCase().contains("place")) {
// change done here to add space if no value
place.add(line.split("=").length > 1 ? line.split("=")[1]
.trim() : " ");
}
if (line.toLowerCase().contains("details")) {
details.add(line.split("=")[1].trim());
}
}
}
Setting question to line doesn't appear to change what line is read later (if you're wanting the line to advance before it hits the while loop).

Output is Displayed in console and not in the File

try {
BufferedReader sc = new BufferedReader(new FileReader("/home/aravind/Desktop/India.txt"));
ArrayList<String> name = new ArrayList<>();
ArrayList<String> Location = new ArrayList<>();
ArrayList<String> Id = new ArrayList<>();
ArrayList<String> Details = new ArrayList<>();
String line = " ";
while ((line = sc.readLine()) != null) {
if (!line.trim().equals("")) {
System.out.println(line);
if (line.toLowerCase().contains("name")) {
name.add(line.split(":")[1].trim());
}
if (line.toLowerCase().contains("Location")) {
Location.add(line.split(":")[1].trim());
}
if (line.toLowerCase().contains("Id")) {
Id.add(line.split(":")[1].trim());
}
if (line.toLowerCase().contains("Details")) {
Details.add(line.split(":")[1].trim());
}
}
}
for (int i = 0; i < name.size(); i++) {
PrintWriter out = new PrintWriter(newFileWriter("output.csv"));
out.println("name;Location;Id;Details;");
out.println(name.get(i) + ";"
+ Location.get(i) + ";"
+ Id.get(i) + ";"
+ Details.get(i) + ";");
out.close();
}
sc.close();
} catch (Exception e) {
}
and my input file looks like
name = abc
id = 123
Place = xyz
Details = some texts with two line
name = aaa
id = 54657
Place = dfd
Details = some texts with some lines
What could be the problem why it is not printing in csv file instead prints o/p in console..Kindly help me
In your file, title and value are always separated by "=", whereas at runtime you trim strings by ":". You should replace ":" by "=", thus your trim result will not be empty at index 1.:
name.add(line.split("=")[1].trim());

Storing a single csv object into an array

hey ive got a chunk of code thats supposed loads lines of csv file into an array of objects:
public static WarehouseItem[] loadRecords(WarehouseItem[] records) {
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
int numRows = 0;
String warehouseItem;
String filename;
filename = ConsoleInput.readLine("Please enter the filename (DataMillion.csv OR DataThousand.csv)");
try {
fileStrm = new FileInputStream(filename);
rdr = new InputStreamReader(fileStrm);
bufRdr = new BufferedReader(rdr);
warehouseItem = bufRdr.readLine();
records[numRows] = new WarehouseItem(warehouseItem); //NULL POINTER EXCEPTION HERE
System.out.println(records[0].toString(records[0].columnVals));
while (warehouseItem != null) {
numRows++;
records[numRows] = new WarehouseItem(warehouseItem);
warehouseItem = bufRdr.readLine();
}
fileStrm.close();
}
catch (IOException e) {
if (fileStrm != null) {
try {
fileStrm.close();
} catch (IOException ex2) {}
}
System.out.println("Error in file processing: " + e.getMessage());
}
main(null);
return records;
}
but when i run it, i get a NullPointerException on the line
records[numRows] = new WarehouseItem(warehouseItem);
is there anything that i missed??
heres the WarehouseItem constructor + toString:
public class WarehouseItem {
String[] columnVals;
int numColumns = 5;
public WarehouseItem(String warehouseItem) {
String key, brand, model, price, weightInKG;
int intWeightInKG;
double doublePrice;
StringTokenizer strTok;
strTok = new StringTokenizer(warehouseItem, ",");
key = strTok.nextToken();
brand = strTok.nextToken();
model = strTok.nextToken();
intWeightInKG = Integer.parseInt(strTok.nextToken());
doublePrice = Double.valueOf(strTok.nextToken());
weightInKG = String.valueOf(intWeightInKG);
price = String.valueOf(doublePrice);
String[] columnVals = {key, brand, model, weightInKG, price};
if(columnVals.length != 5)
throw new IllegalStateException("Invalid CSV: not enough columns");
}
public String toString(String[] columnVals) {
return ("Key: " + columnVals[0] + "\n" +
"Brand: " + columnVals[1] + "\n" +
"Model: " + columnVals[2] + "\n" +
"Weight: " + columnVals[3] + "\n" + " kg" +
"Price: " + "$" + columnVals[4] + "\n");
}
}
What my problem is the values aren't getting stored into the array records properly and im not sure why
You didn't initialize array, that was a cause NullPointerException in your code, but if you can't use array don't use it.
The number of lines might exceed the capacity of array, use List instead
List<WarehouseItem> records = new ArrayList<>();
String line = bufRdr.readLine();
while (line != null) {
WarehauseItem warehauseItem = new WarehauseItem();
records.add(warehauseItem);
warehauseItem.processLine(line);
line = bufRdr.readLine();
}
numRows = records.size();
When you create an array of objects in Java, it is initialized with all nulls. That is why you get a nullpointerexception.
So you need to create an object for each array position. In fact instead of calling a method you could just make that method a constructor; that would be simpler.
I also noticed another mistake: the method sets local variables, which only exist for the lifetime of the method, when in fact it should set instance variables.
Then I noticed a third mistake: You just caught exception, and assumed that that indicated missing columns; in fact it could indicate invalidly-typed data inside a column (e.g. string instead of integer).
You missed object creation records[numRows]=new WarehouseItem();
Your code need to be like this.
while (warehouseItem != null) {
records[numRows]=new WarehouseItem(); //here you forgot the object creation.
warehouseItem = bufRdr.readLine();
records[numRows].processLine(warehouseItem);
numRows++;
}
Because you haven't assigned anything to records[numRows]. You only defined records as an array of WarehouseItem objects.
You should assign a new WarehouseItem to that index of the array before you can use.
records[numRows] = new WarehouseItem();
warehouseItem = bufRdr.readLine();
records[numRows].processLine(wareHouseitem);

java substring within filreader while

Can't find any help on how to do this:
I can't use .substring in the Filreader's while, it throws an exception after reading the first line.
String line = "";
BufferedReader in = new BufferedReader( new FileReader(f) );
LineNumberReader lnr = new LineNumberReader(in);
while ((line = lnr.readLine()) != null) {
System.out.println(lnr.getLineNumber() + " : " + line.substring(1, 7) +"!");
}
in.close();
lnr.close();
Glad that you have already found the answer to your problem, additionally I would like to suggest adding a range check when calling substring (at least in cases where a variable length of line is expected)
if (line.length() > 7) {
System.out.println(lnr.getLineNumber() + " : " + line.substring(1, 7) +"!");
}
else {
System.err.println("Unexpected line, minimum expected length=7 chars");
}

Categories