What is the best/fastest way to load these .csv files? - java

I've been attempting to load 6 .csv files. I've used the CSVReader library, and the BufferedReader one. I noticed that when using the BufferedReader library the files are loaded faster. Nonetheless, this caused me to have an OutOfMemory exception, so I had to set the max memory usage to 1024mb in Eclipse. On the other hand, when I use the CSVReader library I don't get this issue. I'm wondering if there's something wrong in my code, and what could be the best way to load the files considering it to be optimal in terms of speed and memory. Here is my code (I'm using BufferedReader here):
public void loadMovingViolations(int semestre)
{
try
{
String path = ".\\data\\Moving_Violations_Issued_in_";
String mth1Path = "";
String mth2Path = "";
String mth3Path = "";
String mth4Path = "";
String mth5Path = "";
String mth6Path = "";
if (semestre == 1)
{
mth1Path = path + "January_2018.csv";
mth2Path = path + "February_2018.csv";
mth3Path = path + "March_2018.csv";
mth4Path = path + "April_2018.csv";
mth5Path = path + "May_2018.csv";
mth6Path = path + "June_2018.csv";
}
else if (semestre == 2)
{
mth1Path = path + "July_2018.csv";
mth2Path = path + "August_2018.csv";
mth3Path = path + "September_2018.csv";
mth4Path = path + "October_2018.csv";
mth5Path = path + "November_2018.csv";
mth6Path = path + "December_2018.csv";
}
String[] mths = {mth1Path, mth2Path, mth3Path, mth4Path, mth5Path, mth6Path};
String cPath = "";
int numInfracs = 0;
int[] infracs = new int[6];
double xMin = Double.MAX_VALUE, yMin = Double.MAX_VALUE, xMax = 0, yMax = 0;
BufferedReader br = null;
int i = 0;
while (i < mths.length)
{
int tempInfrac = 0;
cPath = mths[i];
br = new BufferedReader(new FileReader(cPath));
String row = br.readLine();
while ( (row = br.readLine()) != null)
{
String[] columns = row.split(",");
String in1 = columns[0];
Integer objId = Integer.parseInt(in1);
String location = columns[2];
String in2 = columns[3];
int adressId = 0;
if ( !(in2.compareTo("") == 0) )
adressId = Integer.parseInt(in2);
String in3 = columns[4];
double streetId = 0;
if ( !(in3.compareTo("") == 0) )
streetId = Double.parseDouble(in3);
String in4 = columns[5];
Double xCord = Double.parseDouble(in4);
String in5 = columns[6];
Double yCord = Double.parseDouble(in5);
String ticketType = columns[7];
String in6 = columns[8];
Integer fineAmt = Integer.parseInt(in6);
String in7 = columns[9];
double totalPaid = Double.parseDouble(in7);
String in8 = columns[10];
Integer penalty1 = Integer.parseInt(in8);
String accident = columns[12];
String date = columns[13];
String vioCode = columns[14];
String vioDesc = columns[15];
VOMovingViolations vomv = new VOMovingViolations(objId, location, adressId, streetId, xCord, yCord, ticketType, fineAmt, totalPaid, penalty1, accident, date, vioCode, vioDesc);
movingViolationsQueue.enqueue(vomv);
tempInfrac++;
if (xCord > xMax)
xMax = xCord;
if (yCord > yMax)
yMax = yCord;
if (xCord < xMin)
xMin = xCord;
if (yCord < yMin)
yMin = yCord;
}
numInfracs += tempInfrac;
infracs[i] = tempInfrac;
i++;
br.close();
}
System.out.println();
int j = 0;
for (int current: infracs)
{
String[] sa = mths[j].substring(35).split("_");
String mth = sa[0];
System.out.println("En el mes " + mth + " se encontraron " +
current + " infracciones");
j++;
}
System.out.println();
System.out.println("Se encontraron " + numInfracs + " infracciones en el semestre.");
System.out.println();
System.out.println("Minimax: " + "("+xMin+", "+yMin+"), " + "("+xMax+", "+yMax+")");
System.out.println();
}
catch (Exception e)
{
e.printStackTrace();
System.out.println();
System.out.println("No se pudieron cargar los datos");
System.out.println();
}
}

Regarding the "better" way, as usual it depends.
You are reinventing the wheel. And it is surprisingly hard to write a fully functional csv parser that works with arbitrary input data. Your parser does a simple split on ",", this means it will fail as soon as one of your columns contains a string with a comma inside! You might also run into trouble when the separation character is changed.
Your code is faster because it omits a ton of things a csv parser can do. Therefore your code works with your table, but if somebody else gives you a valid csv file, your parser will throw exceptions at you. A real csv parser would accept any well formed input!
Thus: if the sole purpose of your code is read files with that given structure, sure, you can use your faster solution. But if you expect that your input data format will change over time, then every update will make you change your code. And worse, such updates might make your code more complicated over time. Therefore you have to carefully balance development efficiency against runtime performance.

Thank you for your answers. I've tried using another library and now it only takes about 1.2 seconds to load the files (I'm loading 600k objects approx.). But i'm still geting OutOfMemory: java heap exception when I don't put Xms512m and Xml1024m in the Eclipse commands. Is there any way to make my loading method use less memory?
public void loadMovingViolations(int semestre)
{
CsvParserSettings settings = new CsvParserSettings();
settings.getFormat().setLineSeparator("\n");
CsvParser parser = new CsvParser(settings);
String path = ".\\data\\Moving_Violations_Issued_in_";
String mth1Path = "";
String mth2Path = "";
String mth3Path = "";
String mth4Path = "";
String mth5Path = "";
String mth6Path = "";
if (semestre == 1)
{
mth1Path = path + "January_2018.csv";
mth2Path = path + "February_2018.csv";
mth3Path = path + "March_2018.csv";
mth4Path = path + "April_2018.csv";
mth5Path = path + "May_2018.csv";
mth6Path = path + "June_2018.csv";
}
else if (semestre == 2)
{
mth1Path = path + "July_2018.csv";
mth2Path = path + "August_2018.csv";
mth3Path = path + "September_2018.csv";
mth4Path = path + "October_2018.csv";
mth5Path = path + "November_2018.csv";
mth6Path = path + "December_2018.csv";
}
String[] mths = {mth1Path, mth2Path, mth3Path, mth4Path, mth5Path, mth6Path};
String cPath = "";
int numInfracs = 0;
int[] infracs = new int[6];
double xMin = Double.MAX_VALUE, yMin = Double.MAX_VALUE, xMax = 0, yMax = 0;
try
{
int i = 0;
while (i < mths.length)
{
int tempInfrac = 0;
cPath = mths[i];
parser.beginParsing(new FileReader(cPath));
parser.parseNext();
String[] row = null;
while((row = parser.parseNext()) != null)
{
String in1 = row[0].toString();
Integer objId = Integer.parseInt(in1);
String location = row[2].toString();
int addressId = 0;
if (row[3] != null)
{
String in2 = row[3].toString();
addressId = Integer.parseInt(in2);
}
double streetId = 0;
if (row[4] != null)
{
String in3 = row[4].toString();
streetId = Double.parseDouble(in3);
}
String in4 = row[5].toString();
Double xCord = Double.parseDouble(in4);
String in5 = row[6].toString();
Double yCord = Double.parseDouble(in5);
String ticketType = row[7].toString();
String in6 = row[8].toString();
Integer fineAmt = Integer.parseInt(in6);
String in7 = row[9].toString();
double totalPaid = Double.parseDouble(in7);
String in8 = row[10].toString();
Integer penalty1 = Integer.parseInt(in8);
String accident = row[12].toString();
String date = "";
if (row[13] != null)
date = row[13].toString();
String vioCode = row[14].toString();
String vioDesc = "";
if (row[15] != null)
vioDesc = row[15].toString();
VOMovingViolations vomv = new VOMovingViolations(objId, location, addressId, streetId, xCord, yCord, ticketType, fineAmt, totalPaid, penalty1, accident, date, vioCode, vioDesc);
queue.enqueue(vomv);
tempInfrac++;
if (xCord > xMax)
xMax = xCord;
if (yCord > yMax)
yMax = yCord;
if (xCord < xMin)
xMin = xCord;
if (yCord < yMin)
yMin = yCord;
}
numInfracs += tempInfrac;
infracs[i] = tempInfrac;
parser.stopParsing();
i++;
}
System.out.println();
int j = 0;
for (int current: infracs)
{
String[] sa = mths[j].substring(35).split("_");
String mth = sa[0];
System.out.println("En el mes " + mth + " se encontraron " +
current + " infracciones");
j++;
}
System.out.println();
System.out.println("Se encontraron " + numInfracs + " infracciones en el semestre.");
System.out.println();
System.out.println("Minimax: " + "("+xMin+", "+yMin+"), " + "("+xMax+", "+yMax+")");
System.out.println();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
System.out.println();
System.out.println("No se encontrĂ³ el archivo");
System.out.println();
}
}

Related

How to speed up reading in input in Java

I am attempting to read in info from files to implement Dijkstra's algorithm. I believe that the double for loop is causing this to drastically slow down, is there anyway around this?
Edge[] edge = new Edge[127807];
int indexEdge = 0;
String line2 = "";
BufferedReader fileReader2 = new BufferedReader(new FileReader("Road.txt"));
String valueString = null;
String vertex1IDName = null;
String vertex2IDName = null;
String extra = null;
float value = 0;
int vertex1ID = 0;
int vertex2ID = 0;
//Read the file line by line
while ((line2 = fileReader2.readLine()) != null)
{
//Get all tokens available in line
String[] tokens2 = line2.split(DELIMITER);
for(String token1 : tokens2)
{
vertex1IDName = tokens2[0];
vertex2IDName = tokens2[1];
valueString = tokens2[2];
if(tokens2.length - 1 == 3) {
extra = tokens2[tokens2.length - 1];
}
else {
extra = "";
}
vertex1ID = Integer.parseInt(vertex1IDName);
vertex2ID = Integer.parseInt(vertex2IDName);
value = Float.parseFloat(valueString);
}
System.out.println("value: "+ value + " vertex1ID:"+ vertex1ID +" vertex2ID:"+ vertex2ID+ " extra:" + extra);
//if vertex 1 name or vertex 2 name in vertex.getID()
for(int i = 0; i< indexVertex; i++) {
for(int j = 0; j< indexVertex; j++) {
if(vertex1ID == vertex[i].getID() && vertex2ID == vertex[j].getID()) {
vertex[i].addNeighbour(edge[indexEdge] = new Edge(value,vertex[i],vertex[j],extra));
indexEdge++;
}
}
}
}

Reading & Breaking CSV File in Java:

I am editing this question to be more specific and I've learned some Jave to find the solution to my problem. I have a file in CSV format like this:
or in excel like this:
Now I am using Java program to read the second line of file and separate each Comma Separated Value and write it to console as well as on other output file and it was done easily. Now I'm trying to break the last value of:
S/1,M/1,L/1,XL/1 | 2XL/1,3XL/1,4XL/1,5XL/1 | MT/1,LT/1 (Original)
S/1,M/1,L/1,XL/1,2XL/1,3XL/1,4XL/1,5XL/1,MT/1,LT/1 (Modified using program to remove spaces and replacing the Pipes (|) with comma.
In each value, There is the size name before Forward Slash (/) and its quantity is after that. What I'm trying is using the Forward Slash (/) to separate the size with its quantity. And the problem is that the size may contain the forward slash as well (e.g. 12/BT or 2BT/2x). I've tried many algorithms like reversing the whole array or storing the slash count but not getting the success. The whole code to read file and break the comma separated values into separate columns of file is as following:
import java.io.*;
import javax.swing.*;
public class ReadFile3c{
public static void main(String args[]){
try{
//Getting File Name
String fileName = JOptionPane.showInputDialog("Enter File Name") + ".csv";
//Creating Stream with File
FileReader fr = new FileReader(fileName);
//Applying Buffer Filter
BufferedReader br = new BufferedReader(fr);
//Reading First line then Second Line
String s = br.readLine();
s = br.readLine();
s = s + ",";//adding comma at the end of the file
s = s.replaceAll("\\s",""); //Eliminating Spaces
s = s.replaceAll("\\|",","); //Replacing Pipes with comma
char charArray[] = s.toCharArray();
//Declaring Strings and variablse for value separating function
int n = 0; //Array Variable
int m = 0; //Array Variable
String[] inverted = new String[3]; //String to store inverted Commas Values
String[] comma = new String[10]; //String to store comma Values
String value = ""; //Storing character values
try{
//Loop to cycle each character of file
for(int j = 0; j<charArray.length;j++){
//Inverted comma value separator
if (charArray[j] == '"') {
j++;
//loop to gather values b/w invreted comma
while((charArray[j] != '"')){
value = value + charArray[j];
j++;
}
inverted[n] = value;
n++;
j++;
value = "";
}else{
j = j - 1;
//comma Value separator
if (charArray[j] == ','){
j++;
//loop to gether values b/w commas
while((charArray[j] !=',')){
value = value + charArray[j];
j++;
}
comma[m] = value;
m++;
value = "";
}
}
}
}catch(Exception ex){
System.out.println("in inner Exception Block" + ex);
}
//declaring variables to storing values
String name, patternCode, placeSizeQty,width,length,utill,pArea,pPerimeter,totalPcs,placePcs,tSizes;
name = inverted[0];
patternCode = inverted[1];
placeSizeQty = inverted[2];
width = comma[0];
length = comma[1];
utill = comma[2];
pArea = comma[3];
pPerimeter = comma[4];
totalPcs = comma[5];
placePcs = comma[6];
tSizes = comma[7];
//printing all values on Console
System.out.println("\nMarkerName: " + name);
System.out.println("Width :" + width);
System.out.println("Length :" + length);
System.out.println("Utill :" + utill);
System.out.println("Place Area :" + pArea);
System.out.println("Place Perimeter :" + pPerimeter);
System.out.println("PatternCode: " + patternCode);
System.out.println("PlaceSizeQty: " + placeSizeQty);
System.out.println("Total Pcs :" + totalPcs);
System.out.println("Place Pcs :" + placePcs);
System.out.println("Total Sizes :" + tSizes);
//Creating Output file
String fileOutput = JOptionPane.showInputDialog("Enter Output File Name") + ".txt";
//File Writer
try{
//Creating Stream with output file
FileWriter fw = new FileWriter(fileOutput);
//Applying Buffring Stream
PrintWriter pw = new PrintWriter(fw);
//Declaration
String outputLine = null;
//Writing Inverted inputs
for (int u = 0; u <=2 ;u++ ) {
outputLine = inverted[u];
pw.println(outputLine);
System.out.println("Writing: " + outputLine);
}//end of for
//writing comma inputs
for (int t = 0;t <=7 ; t++ ) {
outputLine = comma[t];
pw.println(outputLine);
System.out.println("Writing: " + outputLine);
}//end of for
pw.flush();
pw.close();
fw.close();
fr.close();
br.close();
}catch(Exception ex){
System.out.println("Output: " + ex);
}//End of output catch
}catch(IOException ex){
System.out.println(ex);
}//end of catch
}//end of catch
}//end of Class
And the code to Break the Size and quantity and store it in Double array (Not completed) is as Following:
import java.io.*;
import javax.swing.*;
public class ReadFileInvert{
public static void main(String args[]){
try{
String fileName = JOptionPane.showInputDialog("Enter File Name") + ".csv";
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
String s = br.readLine();
System.out.println(s);
s = s.replaceAll("\\s","");
s = s.replaceAll("\\|",",");
System.out.println(s);
char charArray[] = s.toCharArray();
char charArrayI[] = new char[charArray.length + 1];
int j = 0;
String value = "";
for(int i = charArray.length; i > 0; i--){
charArrayI[j] = charArray[i];
value = value + charArrayI[j];
j++;
}
System.out.println("1" + value);
}catch(Exception ex){
System.out.println(ex);
}
}
}
Now in simple I just want to Separate the sizes (Which may contains the Forward Slashes) with its quantity (After last slash of each value) and store it in double array Like charArray[sizeName][Qty]. Sorry if i didn't explained my problem well as I'm Learning the Coding. but I'll provide as much info as you want.
Have you considered looking at the CAD software export to see if there is a solution on the file creation side? Or is this file coming from a third party?
OK. So, after the hard work of whole day, I've found the following solution to my problem:
import java.io.*;
import javax.swing.*;
public class ReadFileInvert2{
public static void main(String args[]){
try{
String fileName = JOptionPane.showInputDialog("Enter File Name") + ".csv";
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
String s = br.readLine();
System.out.println(s);
s = s.replaceAll("\\s","");
s = s.replaceAll("\\|",",");
System.out.println(s);
char charArray[] = s.toCharArray();
int x = charArray.length - 1;
charArray[x] = ',';
int no = 1;
int size = 1;
int qty = 2;
String sizeS = "";
String qtyS = "";
//String resSet[][] = new String[4][2];
String resSize[] = new String[20];
String resQty[] = new String[20];
int slashNo = 0;
String value = "";
for (int j = 1; j < charArray.length; j++){
int n = j;
if (charArray[j] == ','){
j++;
}
while (charArray[j] != ','){
if (charArray[j] == '/') {
slashNo = j;
//j++;
}
value = value + charArray[j];
//System.out.println(value);
j++;
}
for (int k = n;k < slashNo; k++ ) {
sizeS = sizeS + charArray[k];
//System.out.println(sizeS);
}
for (int l = slashNo + 1; l < j; l++ ) {
qtyS = qtyS + charArray[l];
//System.out.println(qtyS);
}
resSize[no] = sizeS;
System.out.println(resSize[no]);
resQty[no] = qtyS;
System.out.println(resQty[no]);
System.out.println("Size is: " + resSize[no] + ", and Qty is: " + resQty[no]);
no++;
slashNo = 0;
sizeS = "";
qtyS = "";
}
String fileOutput = JOptionPane.showInputDialog("Enter Output File Name: ") + ".txt";
try{
FileWriter fw = new FileWriter(fileOutput);
PrintWriter pw = new PrintWriter(fw);
String outputSize = null;
String outputQty = null;
for (int t = 1; t < no; t++) {
outputSize = resSize[t];
outputQty = resQty[t];
pw.println(outputSize + " = " + outputQty);
System.out.println("Writing: "+ outputSize + " = " + outputQty);
}
pw.flush();
pw.close();
fw.close();
fr.close();
br.close();
}catch(Exception ex){
System.out.println("Output " + ex);
}
}catch(Exception ex){
System.out.println(ex);
}
}
}
Now its in Generic form but will improve it later. But still its working fine. Thanks for your Help stack overflow Community.

My array Printing NULL

In the method, i have all these initialize
Scanner input = new Scanner(System.in);
File file = new File("order.dat");
File viewOrder = new File("ViewOrder.dat");
String orderNo, itemNo, itemNameHolder, qtyHolder, priceHolder, status;
int hold, count = 0, countArray = 0;
double tempPriceHolder, totalPrice = 0;
String tempStatus = "";
String[] holdItemNo = null;
String[] holdName = null;
Integer[] holdQty = null;
Double[] holdTotal = null;
String[] holdStatus = null;
After, i try to read all my content in the file and store the content into holdX array
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
while ((line = br.readLine()) != null) {
String tokens[] = line.split(";");
orderNo = tokens[0];
itemNo = tokens[1];
itemNameHolder = tokens[2];
qtyHolder = tokens[3];
priceHolder = tokens[4];
status = tokens[5];
if (orderNo.equalsIgnoreCase(userOrderNo)) {
tempPriceHolder = Double.parseDouble(priceHolder);
hold = Integer.parseInt(qtyHolder);
tempPriceHolder = tempPriceHolder * hold;
totalPrice += tempPriceHolder;
countArray++;
holdItemNo = new String[countArray];
holdName = new String[countArray];
holdQty = new Integer[countArray];
holdTotal = new Double[countArray];
holdStatus = new String[countArray];
if (status.matches("s")) {
tempStatus = "Success";
} else if (status.matches("p")) {
tempStatus = "Partially Full";
} else if (status.matches("o")) {
tempStatus = "Out of Stock";
}
holdItemNo[count] = itemNo;
holdName[count] = itemNameHolder;
holdQty[count] = hold;
holdTotal[count] = tempPriceHolder;
holdStatus[count] = tempStatus;
count++;
}
}
} catch (Exception e) {
System.out.println("Error");
}
Final, i write all my array into a new file.
System.out.printf("%s %15s %15s %10s %10s\n", "Item No", "Description", "Quantity", "Total", "Status");
for (int i = 0; i < holdItemNo.length; i++) {
System.out.printf("\n%-11s %-18s %-13s $%-8s %s \n", holdItemNo[i], holdName[i], holdQty[i], holdTotal[i], holdStatus[i]);
}
System.out.println("-----------------------------------------------------------------------");
System.out.printf("%46s %s\n", "$", totalPrice);
System.out.print("Print Order to file Y/N: ");
String choice = input.next();
if (choice.equalsIgnoreCase("y")) {
try {
PrintWriter bw = new PrintWriter(new FileWriter("ViewOrder.dat", true));
for (int i = 0; i < holdItemNo.length; i++) {
bw.write(userOrderNo + ";" + holdItemNo[i] + ";" + holdName[i] + ";" + holdQty[i] + ";" + holdTotal[i] + ";" + holdStatus[i] + "\n");
bw.flush();
}
bw.flush();
bw.close();
System.out.println("Sucessfull!");
} catch (Exception e) {
System.out.println("Error");
}
} else if (choice.equalsIgnoreCase("n")) {
System.out.println("");
}
but the problem is even my code is working but the output is not what i expected. It printed out the printed out the last content and also the sub price is working as well but the rest is only printed out NULL.
Example
Also, it gave me warning of Derefencing possible null pointer on the array.length
for (int i = 0; i < holdItemNo.length; i++) {
bw.write(userOrderNo + ";" + holdItemNo[i] + ";" + holdName[i] + ";" + holdQty[i] + ";" + holdTotal[i] + ";" + holdStatus[i] + "\n");
bw.flush();
}
Guessing:
holdItemNo = new String[countArray];
and the following lines: you are creating these new array objects within your reading loop (inside a condition).
So probably that condition never goes true; therefore your arrays stay all null. But even when the condition is met - you probably expect that to happen more then once. And guess what: you are creating completely new arrays then. While throwing away the previously created array. Each time the if condition turns true you will lose previously stored values!
So the answer is: create your arrays before entering the loop. This means that you either have to query "how many slots to create" upfront; or you have to create an array with say 100 empty slots; and within your loop you then have to check if you still have free slots.
Or you start using java.util.List resp. ArrayList - which allows for dynamic adding of elements.

Getter within loop returning null after assigning values

I've got a slight problem with my program. Simply put, what I do is this:
Choose the option to "Add a new Student record".
When I try to display the newly added values (First Name, Last Name, Course), it all comes back as null.
I can't wrap my head around what's wrong, but I'll try to post the needed codes in order for all of you to get a better view.
Main class:
public static void main(String[] args) throws Exception{
String cont1=" ";
String X;
int x1,arr_count=1;
String[] option = {"First Name","Last Name","Course"};
BufferedReader reader1=new BufferedReader(new InputStreamReader(System.in));
do{
System.out.println("\nWelcome! Please select a task: \nA. View a record.\nB. Add a record.\nC. Edit a record.\nD. Exit the program.");
String option1 = reader1.readLine();
if("a".equals(option1)|| "A".equals(option1)){
System.out.println("Please enter the Student ID for the record to view.");
String a = reader1.readLine();
x1 = Integer.parseInt(a);
for(int y=0;y<3;y++){
System.out.print(Records.getRecord(x1,y) + " ");
}
System.out.print("\nSubjects and Grades: \n");
for(int y=3;y<6;y++){
System.out.print(Records.getRecord(x1,y) + " (" + Records.getRecord(x1,y+3) + ")\n");
}
System.out.println("\nReturn to Main Menu? (Y/N)");
cont1= reader1.readLine();
}
else if("b".equals(option1)||"B".equals(option1)){
arr_count++;
for (int y = 0; y<3;y++){
System.out.println("Enter Value for "+ option [y]+":" );
X = reader1.readLine();
X = Records.getRecord(arr_count,y);
}
System.out.println("\nNew Student added:\nID number: "+ arr_count);
for(int y=0;y<3;y++){
X = Records.getRecord(arr_count,y);
System.out.print(X + " ");
}
Records class:
public class Records {
public static String getRecord(int recordID,int index1)throws Exception{
//BufferedReader reader1=new BufferedReader(new InputStreamReader(System.in));
String records[][] = new String [10][9];
records[0][0] = "John"; records[0][3] = "English"; records[0][6] = "C";
records[0][1] = "Smith"; records[0][4] = "Math"; records[0][7] = "B";
records[0][2] = "BS IT"; records[0][5] = "Graphics"; records[0][8] = "A";
records[1][0] = "Juan"; records[1][3] = "Graphics"; records[1][6] = "B";
records[1][1] = "Ponce"; records[1][4] = "Math"; records[1][7] = "B";
records[1][2] = "BS ECE"; records[1][5] = "Robotics"; records[1][8] = "A";
/**records[2][0] = ""; records[2][3] = ""; records[2][6] = "";
records[2][1] = ""; records[2][4] = ""; records[2][7] = "";
records[2][2] = ""; records[2][5] = ""; records[2][8] = "";
records[3][0] = ""; records[3][3] = ""; records[3][6] = "";
records[3][1] = ""; records[3][4] = ""; records[3][7] = "";
records[3][2] = ""; records[3][5] = ""; records[3][8] = "";
records[4][0] = ""; records[4][3] = ""; records[4][6] = "";
records[4][1] = ""; records[4][4] = ""; records[4][7] = "";
records[4][2] = ""; records[4][5] = ""; records[4][8] = "";*/
return records[recordID][index1];
}
}
I've tried to set blank values to the records array, also putting the function which assigns the new values to the array into the Records class but I still can't find a way to make this work.
You never set the value of the record.
X = reader1.readLine();
X = Records.getRecord(arr_count,y);
Is discarding the value read. Create a setValue method in your Record class -
X = reader1.readLine();
Records.setValue(arr_count, y, X);
--- inRecord
setValue ( x, y, val ) {
records[x][y] = val;
}
It seems your Main class is not complete. What is the condition for the do while loop to stop? Is there anything else in the main method than this loop?

Exception in thread "main" java.lang.NullPointerException when trying to update file

I'm in a beginner CS class and I'm trying to update info in a file. The info in the array does get replaced temporarily; however, I am unable to save the changes to the file. And, even after it's replaced, I get the "null" error.
Here is my code, I have omitted the lines and methods that are unrelated:
public static void readData(){
// Variables
int choice2, location;
// Read file
File dataFile = new File("C:/Users/shirley/Documents/cddata.txt");
FileReader in;
BufferedReader readFile;
// Arrays
String[] code = new String[100];
String[] type = new String[100];
String[] artist = new String[100];
String[] song = new String[100];
Double[] price = new Double[100];
Double[] vSales = new Double[100];
// Split Variables
String tempCode, tempType, tempArtist, tempSong, tempPrice, tempVsales;
// Split
String text;
int c = 0;
try{
in = new FileReader(dataFile);
readFile = new BufferedReader(in);
while ((text = readFile.readLine()) != null){
// Split line into temp variables
tempCode = text.substring(0,5);
tempType = text.substring(5,15);
tempArtist = text.substring(16,30);
tempSong = text.substring(30,46);
tempPrice = text.substring(46,52);
tempVsales = text.substring(52);
// Place text in correct arrays
code[c] = tempCode;
type[c] = tempType;
artist[c] = tempArtist;
song[c] = tempSong;
price[c] = Double.parseDouble(tempPrice);
vSales[c] = Double.parseDouble(tempVsales);
c += 1; // increase counter
}
// Output to user
Scanner kb = new Scanner(System.in);
System.out.print("\nSelect another number: ");
choice2 = kb.nextInt();
// Reads data
if (choice2 == 5){
reqStatsSort(code,type,artist,song,price,vSales,c);
location = reqStatistics(code,type,artist,song,price,vSales,c);
if (location == -1){
System.out.println("Sorry, code not found.");
}
else{
System.out.print("Enter new volume sales: ");
vSales[location] = kb.nextDouble();
}
displayBestSellerArray(type,artist,song,vSales,c);
readFile.close();
in.close();
changeVolume(code,type,artist,song,price,vSales,c); // Method to rewrite file
readData();
}
}catch(FileNotFoundException e){
System.out.println("File does not exist or could not be found.");
System.err.println("FileNotFoundException: " + e.getMessage());
}catch(IOException e){
System.out.println("Problem reading file.");
System.err.println("IOException: " + e.getMessage());
}
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
///////////////// REQ STATS SORT METHOD ////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
public static void reqStatsSort(String[] sortCode, String[] sortType, String[] sortArtist,
String[] sortSong, Double[] sortPrice, Double[] sortVSales, int c){
// Variables
String tempCode, tempArtist, tempType, tempSong;
double tempVsales, tempPrice;
for(int j = 0; j < (c - 1); j++){
for (int k = j + 1; k < c; k++){
if ((sortCode[k]).compareToIgnoreCase(sortCode[j]) < 0){
// Switch CODE
tempCode = sortCode[k];
sortCode[k] = sortCode[j];
sortCode[j] = tempCode;
// Switch TYPE
tempType = sortType[k];
sortType[k] = sortType[j];
sortType[j] = tempType;
// Switch ARTIST
tempArtist = sortArtist[k];
sortArtist[k] = sortArtist[j];
sortArtist[j] = tempArtist;
// Switch SONG
tempSong = sortSong[k];
sortSong[k] = sortSong[j];
sortSong[j] = tempSong;
// Switch VOLUME
tempVsales = sortVSales[k];
sortVSales[k] = sortVSales[j];
sortVSales[j] = tempVsales;
// Switch PRICE
tempPrice = sortPrice[k];
sortPrice[k] = sortPrice[j];
sortPrice[j] = tempPrice;
}
}
}
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////////// REQUEST STATISTICS METHOD //////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
public static int reqStatistics(String[] statsCode, String[] statsType,
String[] statsArtist, String[] statsSong, Double[] statsPrice,
Double[] statsVSales, int c){
// Variables
String cdCode;
// Obtain input from user
Scanner kb = new Scanner(System.in);
System.out.print("Enter a CD code: ");
cdCode = kb.nextLine();
// Binary search
int position;
int lowerbound = 0;
int upperbound = c - 1;
// Find middle position
position = (lowerbound + upperbound) / 2;
while((statsCode[position].compareToIgnoreCase(cdCode) != 0) && (lowerbound <= upperbound)){
if((statsCode[position].compareToIgnoreCase(cdCode) > 0)){
upperbound = position - 1;
}
else {
lowerbound = position + 1;
}
position = (lowerbound + upperbound) / 2;
}
if (lowerbound <= upperbound){
return(position);
}
else {
return (-1);
}
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////////// BEST SELLER ARRAY METHOD //////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
public static void displayBestSellerArray (String[] displaySortedType,
String[] displaySortedArtist, String[] displaySortedSong,
Double[] displaySortedVSales, int c){
// Output to user
System.out.println();
System.out.println("MUSIC ARTIST HIT SONG VOLUME");
System.out.println("TYPE SALES");
System.out.println("--------------------------------------------------------------------");
for (int i = 0; i < c; i++){
System.out.print(displaySortedType[i] + " " + displaySortedArtist[i] + " "
+ displaySortedSong[i] + " ");
System.out.format("%6.0f",displaySortedVSales[i]);
System.out.println();
}
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////// CHANGE VOLUME METHOD ////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
public static void changeVolume(String[] writeCode, String[] writeType,
String[] writeArtist, String[] writeSong, Double[] writePrice,
Double[] writeVSales, int c){
File textFile = new File("C:/Users/shirley/Documents/cddata.txt");
FileWriter out;
BufferedWriter writeFile;
// Variables
String entireRecord, tempVSales;
int decLoc;
try{
out = new FileWriter(textFile);
writeFile = new BufferedWriter(out);
// Output to user
for (int i = 1; i <= c; i++){
// Convert volume sales to String
tempVSales = Double.toString(writeVSales[i]);
// Get rid of decimals
decLoc = (tempVSales.indexOf("."));
tempVSales = tempVSales.substring(0,decLoc);
// Create record line
entireRecord = writeCode[i] + " " + writeType[i] + " " + writeArtist[i]
+ " " + writeSong[i] + " " + writePrice[i] + " " + tempVSales;
// Write record to file
writeFile.write(entireRecord);
if (i != c){
writeFile.newLine();
}
}
writeFile.close();
out.close();
System.out.println("Data written to file.");
}
catch(IOException e){
System.out.println("Problem writing to file.");
System.out.println("IOException: " + e.getMessage());
}
}
The last method, changeVolume(), is what isn't working. The error I get is
Exception in thread "main" java.lang.NullPointerException
at culminating3.Culminating3.changeVolume(Culminating3.java:508)
at culminating3.Culminating3.readData(Culminating3.java:185)
at culminating3.Culminating3.readData(Culminating3.java:167)
at culminating3.Culminating3.main(Culminating3.java:47)
Java Result: 1
Line 508 is:
tempVSales = Double.toString(writeVSales[i]);
in the changeVolume method().
So my program asks the user for a CD code to change the volume of sales, and sorts the arrays to perform a binary search if the inputted code exists. If it does, my program replaces the old volume of sales (which it does), and saves it with the changeVolume() method (which it doesn't do and gives me the error).
Please keep in mind I'm a newbie. It looks fine to me but I can't figure out why it's not working. I apologize for any messes in the code. writeVSales[] shouldn't be null because I assigned input in the readData() method?
Problem is here:
// Convert volume sales to String
tempVSales = Double.toString(writeVSales[i]);
// Get rid of decimals
decLoc = (tempVSales.indexOf("."));
tempVSales = tempVSales.substring(0,decLoc);
I suggest you to take some sample values and work on this first.
You can use StringTokenizer to perform this.
When you input the information into the writeVSales array you start at 0 (good) and increment c everytime a new item is added, whether or not there is a new item to add or not (again this is fine).
int c = 0;
try{
in = new FileReader(dataFile);
readFile = new BufferedReader(in);
while ((text = readFile.readLine()) != null){
// Split line into temp variables
tempCode = text.substring(0,5);
tempType = text.substring(5,15);
tempArtist = text.substring(16,30);
tempSong = text.substring(30,46);
tempPrice = text.substring(46,52);
tempVsales = text.substring(52);
// Place text in correct arrays
code[c] = tempCode;
type[c] = tempType;
artist[c] = tempArtist;
song[c] = tempSong;
price[c] = Double.parseDouble(tempPrice);
vSales[c] = Double.parseDouble(tempVsales);
c += 1; // increase counter
}
Later in changeVolume() your for loop starts at 1 and goes to c. So you are missing the first element and trying to add an element from an index that is null, hence the `NullPointerexception.
// Output to user
for (int i = 1; i <= c; i++){
//code
}
Change the for loop to start and 0 and go to i < c (i.e. c - 1):
for (int i = 0; i < c; i++){
// Convert volume sales to String
tempVSales = Double.toString(writeVSales[i]);
// Get rid of decimals
decLoc = (tempVSales.indexOf("."));
tempVSales = tempVSales.substring(0,decLoc);
// Create record line
entireRecord = writeCode[i] + " " + writeType[i] + " " + writeArtist[i]
+ " " + writeSong[i] + " " + writePrice[i] + " " + tempVSales;
// Write record to file
writeFile.write(entireRecord);
if (i != c){
writeFile.newLine();
}
}

Categories