Parsing Data from CSV to Array in Java - java

I'm trying to import a CSV file into an array that I can use within a Java program. The CSV file has successfully imported itself and the output appears on Terminal but it throws the error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at CompareCSV.main(CompareCSV.java:19)
at the end. In addition, when I try to call up elements in the array, it also shows the same error. My code is below:
import java.io.*;
import java.util.*;
public class CompareCSV {
public static void main(String[] args) {
String fileName = "sampledata1.csv";
try {
BufferedReader br = new BufferedReader( new FileReader(fileName));
String strLine = null;
StringTokenizer st = null;
int lineNumber = 0, tokenNumber = 0;
while((fileName = br.readLine()) != null) {
lineNumber++;
String[] result = fileName.split(",");
for (int x=0; x<result.length; x++) {
System.out.println(result[x]);
}
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

You are much better off using a proper CSV parser than hacking a faulty one up yourself: http://opencsv.sourceforge.net/
CSV is not the simple format one might be let to think (yes, a line can contain a , that does not separate two pieces of data).

This is the answer for above Question
public class Readline {
/**
* #param args
*/
public static void main(String[] args) {
String fileName = "C:/Users/karthikrao/Desktop/cvsFile.csv";
ArrayList<Integer> margins = new ArrayList<Integer>();
BufferedReader br;
String line, token;
int i;
try {
br = new BufferedReader(new FileReader(fileName));
try {
while ((line = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(line, ",\"");
i = 0;
while (st.hasMoreTokens()) {
token = st.nextToken();
if (margins.size() <= i) {
margins.add((Integer) token.length());
} else {
margins.set(
i,
Math.max(margins.get(i),
(Integer) token.length()));
}
i++;
}
}
br = new BufferedReader(new FileReader(fileName));
while ((line = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(line, ",\"");
i = 0;
while (st.hasMoreTokens()) {
token = st.nextToken();
System.out.print(token);
for (int j = 0; j < margins.get(i) - token.length(); j++) {
System.out.print(" ");
}
System.out.print("|");
i++;
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}

I suggest you not re-inventing wheel when there are so many great libraries out there. Try the uniVocity-parsers with the following code snippt as reference:
public static void main(String[] args) throws FileNotFoundException {
/**
* ---------------------------------------
* Read CSV rows into 2-dimensional array
* ---------------------------------------
*/
// 1st, creates a CSV parser with the configs
CsvParser parser = new CsvParser(new CsvParserSettings());
// 2nd, parses all rows from the CSV file into a 2-dimensional array
List<String[]> resolvedData = parser.parseAll(new FileReader("/examples/example.csv"));
// 3rd, process the 2-dimensional array with business logic
// ......
}
As you can see, only 2 lines required to finish the task of parsing csv data into array. Additionally, the library provides full list of features in parsing CSV data with excellent performance.

Looks like your assumption, that a line in the file always has three columns isn't true for all lines. Replace the for loop statement with the following line to eliminate the exception and see, why it happend:
for (int x=0; x<result.length; x++)

Related

how can I write a code to read each name in a file

I typed 3 names in the file, and I wanted to write a code to count how many times each name was repeated (Example: Alex was repeated in the file 3 times..and so on). The code I wrote only counted each name once, and this is wrong because the names were repeated more than once. Can you help me with the part that could be the cause of this problem?
public class MainClass {
public static void readFile() throws IOException {
//File file;
FileWriter writer=null;
String name, line;
List <String> list = new ArrayList <>();
int countM = 0, countAl = 0, countAh = 0;
try
{
File file = new File("\\Users\\Admin\\Desktop\\namesList.txt");
Scanner scan = new Scanner(file);
while(scan.hasNextLine()) {
line = scan.nextLine();
list.add(line);
}
for (int i=0; i<list.size(); i++)
{
name=list.get(i);
if (name.equals("Ali"))
{
countAl= +1;
}
if (name.equals("Ahmed"))
{
countAh= +1;
}
if (name.equals("Muhammad"))
{
countM = +1;
}
}
Collections.sort(list);
writer = new FileWriter("\\Users\\Admin\\Desktop\\newNameList");
for(int i=0; i<list.size(); i++)
{
name = list.get(i);
writer.write(name +"\n");
}
writer.close();
System.out.println("How many times is the name (Ali) in the file? " + countAl);
System.out.println("How many times is the name (Ahmed) in the file? " + countAh);
System.out.println("How many times is the name (Muhammad) in the file? " + countM);
}
catch(IOException e) {
System.out.println(e.toString());
}
}
public static void main(String[] args) throws IOException {
readFile();
}
}
You an do this much simpler:
//Open a reader, this is autoclosed so you don't need to worry about closing it
try (BufferedReader reader = new BufferedReader(new FileReader("path to file"))) {
//Create a map to hold the counts
Map<String, Integer> nameCountMap = new HashMap<>();
//read all of the names, this assumes 1 name per line
for (String name = reader.readLine(); name != null; name = reader.readLine()) {
//merge the value into the count map
nameCountMap.merge(name, 1, (o, n) -> o+n);
}
//Print out the map
System.out.println(nameCountMap);
} catch (IOException e) {
e.printStackTrace();
}
try:
for (int i=0; i<list.size(); i++)
{
name=list.get(i);
if (name.equals("Ali"))
{
countAl += 1;
}
if (name.equals("Ahmed"))
{
countAh += 1;
}
if (name.equals("Muhammad"))
{
countM += 1;
}
}
This works with me.
+= is not same =+
You need to process each line bearing in mind that the file may be very large in some cases. Better safe than sorry. You need to consider a solution that does not take up so much resources.
Streaming Through the File
I'm going to use a java.util.Scanner to run through the contents of the file and retrieve lines serially, one by one:
FileInputStream inputStream = null;
Scanner sc = null;
try {
inputStream = new FileInputStream(file_path);
sc = new Scanner(inputStream, "UTF-8");
while (sc.hasNextLine()) {
String line = sc.nextLine();
// System.out.println(line);
}
// note that Scanner suppresses exceptions
if (sc.ioException() != null) {
throw sc.ioException();
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (sc != null) {
sc.close();
}
}
This solution will iterate through all the lines in the file – allowing for processing of each line – without keeping references to them – and in conclusion, without keeping them in memory:
Streaming With Apache Commons IO
The same can be achieved using the Commons IO library as well, by using the custom LineIterator provided by the library:
LineIterator it = FileUtils.lineIterator(your_file, "UTF-8");
try {
while (it.hasNext()) {
String line = it.nextLine();
// do something with line
}
} finally {
LineIterator.closeQuietly(it);
}
Since the entire file is not fully in memory – this will also result in pretty conservative memory consumption numbers.
BufferedReader
try (BufferedReader br = Files.newBufferedReader(Paths.get("file_name"), StandardCharsets.UTF_8)) {
for (String line = null; (line = br.readLine()) != null;) {
// Do something with the line
}
}
ByteBuffer
try (SeekableByteChannel ch = Files.newByteChannel(Paths.get("test.txt"))) {
ByteBuffer bb = ByteBuffer.allocateDirect(1000);
for(;;) {
StringBuilder line = new StringBuilder();
int n = ch.read(bb);
// Do something with the line
}
}
The above examples will process lines in a large file without iteratively, without exhausting the available memory – which proves quite useful when working with these large files.

Is it possible to read data from file and store it into 2d Array,when we don't know the number of line in the file,in java

I have to read data from file Here is data and want plot a graph vs thick(column 1 in data) and alpha(column 3) for every model. Every model has 7 line data,the last that start with 0 not required. Here is my code. it works but i don't think it is good code.please, suggest me better way to do the same.
public class readFile {
public static int showLines(String fileName) {
String line;
int currentLineNo = 0;
BufferedReader in = null;
try {
in = new BufferedReader (new FileReader(fileName));
//read until endLine
while(((line = in.readLine()) != null)) {
if (!line.contains("M") && !line.contains("#") && !line.trim().startsWith("0")) {
//skipping the line that start with M, # and 0.
currentLineNo++;
}
}
} catch (IOException ex) {
System.out.println("Problem reading file.\n" + ex.getMessage());
} finally {
try { if (in!=null) in.close(); } catch(IOException ignore) {}
}
return currentLineNo;
}
//Now we know the dimension of matrix, so storing data into matrix
public static void readData(String fileName,int numRow) {
String line;
String temp []=null;
String data [][]=new String[numRow][10];
int i=0;
BufferedReader in = null;
try {
in = new BufferedReader (new FileReader(fileName));
//read until endLine
while(((line = in.readLine()) != null)) {
if (!line.contains("M") && !line.contains("#") && !line.trim().startsWith("0")) {
temp=(line.trim().split("[.]"));
for (int j = 0; j<data[i].length; j++) {
data[i][j] =temp[j];
}
i++;
}
}
// Extract one column from 2d matrix
for (int j = 0; j <numRow; j=j+6) {
for (int j2=j; j2 <6+j; j2++) {
System.out.println(Double.parseDouble(data[j2][0])+"\t"+Double.parseDouble(data[j2][2]));
//6 element of every model, col1 and col3
// will add to dataset.
}
}
} catch (IOException ex) {
System.out.println("Problem reading file.\n" + ex.getMessage());
} finally {
try { if (in!=null) in.close(); } catch(IOException ignore) {}
}
}
//Main Method
public static void main(String[] args) {
//System.out.println(showLines("rf.txt"));
readData("rf.txt",showLines("rf.txt") );
}
}
as johnchen902 implies use a list
List<String> input=new ArrayList<String>();
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
input.add(line);
}
br.close();
int N=input.get(0).split(",").size(); // here add your delimiter
int M=input.size();
String[][] data=new String[M][N]
for (int i=0;i<M;i++){
String[] parts = string.split("-");
for (int k=0;k<n;k++){
data[i][k]=parts[k];
}
}
something like that
hope it helps. plz put more effort into asking the question. Give us the needed Input files, and the Code you came up with until now to solve the problem yourself.

How do you store each value separately using comma then they store into separate array?

A simple data file which contains
1908,Souths,Easts,Souths,Cumberland,Y,14,12,4000
1909,Souths,Balmain,Souths,Wests,N
Each line represents a season of premiership and has the following format: year, premiers, runners up, minor premiers, wooden spooners, Grand Final held, winning score,
losing score, crowd
I know how to store a data into an array and use the delimiter, but I am not exactly sure how to store EACH data item by a comma into separate arrays? Some suggestions and what particular code to be used would be nice.
UPDATE:
I just added the code but it still didn't work. Here's the code:
import java.io.*;
import java.util.Scanner;
public class GrandFinal {
public static Scanner file;
public static String[] array = new String[1000];
public static void main(String[] args) throws FileNotFoundException {
File myfile = new File("NRLdata.txt");
file = new Scanner (myfile);
Scanner s = file.useDelimiter(",");
int i = 0;
while (s.hasNext()) {
i++;
array[i] = s.next();
}
for(int j=0; j<array.length; j++) {
if(array[j] == null)
;
else if(array[j].contains("Y"))
System.out.println(array[j] + " ");
}
}
}
Here you go. Use ArrayList. Its dynamic and convenient.
BufferedReader br = null;
ArrayList<String> al = new ArrayList();
String line = "";
try {
br = new BufferedReader(new FileReader("NRLdata.txt"));
while ((line = br.readLine()) != null) {
al.add(line);
}
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
What does not work in your case ?
Because your season array is empty. You need to define the length, for ex:
private static String[] season = new String[5];
This is not right because you don't know how many lines you are going to store. Which is why I suggested you to Use ArrayList.
After working around a bit, I have come up with following code:
private static File file;
private static BufferedReader counterReader = null;
private static BufferedReader fileReader = null;
public static void main(String[] args) {
try {
file = new File("C:\\Users\\rohitd\\Desktop\\NRLdata.txt");
counterReader = new BufferedReader(new FileReader(file));
int numberOfLine = 0;
String line = null;
try {
while ((line = counterReader.readLine()) != null) {
numberOfLine++;
}
String[][] storeAnswer = new String[9][numberOfLine];
int counter = 0;
fileReader = new BufferedReader(new FileReader(file));
while ((line = fileReader.readLine()) != null) {
String[] temp = line.split(",");
for (int j = 0; j < temp.length; j++) {
storeAnswer[j][counter] = temp[j];
System.out.println(storeAnswer[j][counter]);
}
counter++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
catch (FileNotFoundException e) {
System.out.println("Unable to read file");
}
}
I have added counterReader and fileReader; which are used for counting number of lines and then reading the actual lines. The storeAnswer 2d array contains the information you need.
I hope the answer is better now.

How to read a line from file given its number?

I have a file that contain 100 line
each line contain one tag
I need to obtain the tag value given its rank which is the "id" of TagVertex Class
public abstract class Vertex <T>{
String vertexId ;// example Tag1
T vertexValue ;
public abstract T computeVertexValue();
}
public class TagVertex extends Vertex<String> {
#Override
public String computeVertexValue() {
// How to get the String from my file?
return null;
}
T try this but it doesnt work
public static void main(String args[]) {
File source //
int i=90;
int j=0;
String s = null;
try {
Scanner scanner = new Scanner(source);
while (scanner.hasNextLine()) {
if (j==i) s= scanner.nextLine();
else j++;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(s);
}}
Although there is a way to skip characters with BufferedReader, I don't think there's is a built-in way to skip whole lines.
BufferedReader bf = new BufferedReader(new FileReader("MyFile.txt"));
for(int i = 1; i < myVertex.vertexId; i++){
bf.readLine();
}
String n = bf.readLine();
if(n != null){
System.out.println(n);
}
I think there may be a better idea though.
This is command u can use to read from file:
BufferedReader bf = new BufferedReader(new FileReader("filename"));
This will read the file to the buffer.
Now, for reading each line u should use a while loop and read each line into string.
Like:
String str;
while((str = bf.readLine()) != null){
//handle each line untill the end of file which will be null and quit the loop
}

Find a specific line of a text file (not by line_number) and store it as a new String

I am trying to read a text file in java using FileReader and BufferedReader classes. Following an online tutorial I made two classes, one called ReadFile and one FileData.
Then I tried to extract a small part of the text file (i.e. between lines "ENTITIES" and "ENDSEC"). Finally l would like to tell the program to find a specific line between the above-mentioned and store it as an Xvalue, which I could use later.
I am really struggling to figure out how to do the last part...any help would be very much apprciated!
//FileData Class
package textfiles;
import java.io.IOException;
public class FileData {
public static void main (String[] args) throws IOException {
String file_name = "C:/Point.txt";
try {
ReadFile file = new ReadFile (file_name);
String[] aryLines = file.OpenFile();
int i;
for ( i=0; i < aryLines.length; i++ ) {
System.out.println( aryLines[ i ] ) ;
}
}
catch (IOException e) {
System.out.println(e.getMessage() );
}
}
}
// ReadFile Class
package textfiles;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.lang.String;
public class ReadFile {
private String path;
public ReadFile (String file_path) {
path = file_path;
}
public String[] OpenFile() throws IOException {
FileReader fr = new FileReader (path);
BufferedReader textReader = new BufferedReader (fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
String nextline = "";
int i;
// String Xvalue;
for (i=0; i < numberOfLines; i++) {
String oneline = textReader.readLine();
int j = 0;
if (oneline.equals("ENTITIES")) {
nextline = oneline;
System.out.println(oneline);
while (!nextline.equals("ENDSEC")) {
nextline = textReader.readLine();
textData[j] = nextline;
// xvalue = ..........
j = j + 1;
i = i+1;
}
}
//textData[i] = textReader.readLine();
}
textReader.close( );
return textData;
}
int readLines() throws IOException {
FileReader file_to_read = new FileReader (path);
BufferedReader bf = new BufferedReader (file_to_read);
String aLine;
int numberOfLines = 0;
while (( aLine = bf.readLine()) != null ) {
numberOfLines ++;
}
bf.close ();
return numberOfLines;
}
}
I don't know what line you are specifically looking for but here are a few methods you might want to use to do such operation:
private static String START_LINE = "ENTITIES";
private static String END_LINE = "ENDSEC";
public static List<String> getSpecificLines(Srting filename) throws IOException{
List<String> specificLines = new LinkedList<String>();
Scanner sc = null;
try {
boolean foundStartLine = false;
boolean foundEndLine = false;
sc = new Scanner(new BufferedReader(new FileReader(filename)));
while (!foundEndLine && sc.hasNext()) {
String line = sc.nextLine();
foundStartLine = foundStartLine || line.equals(START_LINE);
foundEndLine = foundEndLine || line.equals(END_LINE);
if(foundStartLine && !foundEndLine){
specificLines.add(line);
}
}
} finally {
if (sc != null) {
sc.close();
}
}
return specificLines;
}
public static String getSpecificLine(List<String> specificLines){
for(String line : specificLines){
if(isSpecific(line)){
return line;
}
}
return null;
}
public static boolean isSpecific(String line){
// What makes the String special??
}
When I get it right you want to store every line between ENTITIES and ENDSEC?
If yes you could simply define a StringBuffer and append everything which is in between these to keywords.
// This could you would put outside the while loop
StringBuffer xValues = new StringBuffer();
// This would be in the while loop and you append all the lines in the buffer
xValues.append(nextline);
If you want to store more specific data in between these to keywords then you probably need to work with Regular Expressions and get out the data you need and put it into a designed DataStructure (A class you've defined by our own).
And btw. I think you could read the file much easier with the following code:
BufferedReader reader = new BufferedReader(new
InputStreamReader(this.getClass().getResourceAsStream(filename)));
try {
while ((line = reader.readLine()) != null) {
if(line.equals("ENTITIES") {
...
}
} (IOException e) {
System.out.println("IO Exception. Couldn't Read the file!");
}
Then you don't have to read first how many lines the file has. You just start reading till the end :).
EDIT:
I still don't know if I understand that right. So if ENTITIES POINT 10 1333.888 20 333.5555 ENDSEC is one line then you could work with the split(" ") Method.
Let me explain with an example:
String line = "";
String[] parts = line.split(" ");
float xValue = parts[2]; // would store 10
float yValue = parts[3]; // would store 1333.888
float zValue = parts[4]; // would store 20
float ... = parts[5]; // would store 333.5555
EDIT2:
Or is every point (x, y, ..) on another line?!
So the file content is like that:
ENTITIES POINT
10
1333.888 // <-- you want this one as xValue
20
333.5555 // <-- and this one as yvalue?
ENDSEC
BufferedReader reader = new BufferedReader(new
InputStreamReader(this.getClass().getResourceAsStream(filename)));
try {
while ((line = reader.readLine()) != null) {
if(line.equals("ENTITIES") {
// read next line
line = reader.readLine();
if(line.equals("10") {
// read next line to get the value
line = reader.readLine(); // read next line to get the value
float xValue = Float.parseFloat(line);
}
line = reader.readLine();
if(line.equals("20") {
// read next line to get the value
line = reader.readLine();
float yValue = Float.parseFloaT(line);
}
}
} (IOException e) {
System.out.println("IO Exception. Couldn't Read the file!");
}
If you have several ENTITIES in the file you need to create a class which stores the xValue, yValue or you could use the Point class. Then you would create an ArrayList of these Points and just append them..

Categories