I am trying to read the csv file, "read_ex.csv", into an array. I have searched endlessly on the web/stackoverflow to find a way to read the file into an array. The best i have been able to do is read it in a streaming fashion, but I cant store it in an array due the variable size of the file. I belive that ArrayList is a method to deal with variable size array, but I don't know how to work with it. Essentially I want to be able to access the String array "values" after the while loop finishes.
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.File;
public class sortarray {
public static void main (String []agrs){
String fileName= "read_ex.csv";
File file= new File(fileName);
try{
Scanner inputStream= new Scanner(file);
while(inputStream.hasNext()){
String data= inputStream.next();
String[] values = data.split(",");
System.out.println(values[1]);
}
inputStream.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}
//This prints out the working directory
System.out.println("Present Project Directory : "+ System.getProperty("user.dir"));
}
}
Although using the Apache CSV library as mentioned by #Minjun.Y is perfectly fine, I try to provide a solution that is closer to your code and maybe easier for you to follow:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class CsvParser {
public static void main(String[] args) {
String fileName= "read_ex.csv";
File file= new File(fileName);
// this gives you a 2-dimensional array of strings
List<List<String>> lines = new ArrayList<>();
Scanner inputStream;
try{
inputStream = new Scanner(file);
while(inputStream.hasNext()){
String line= inputStream.next();
String[] values = line.split(",");
// this adds the currently parsed line to the 2-dimensional string array
lines.add(Arrays.asList(values));
}
inputStream.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}
// the following code lets you iterate through the 2-dimensional array
int lineNo = 1;
for(List<String> line: lines) {
int columnNo = 1;
for (String value: line) {
System.out.println("Line " + lineNo + " Column " + columnNo + ": " + value);
columnNo++;
}
lineNo++;
}
}
}
Let's go through it step-by-step:
I added 3 more imports: ArrayList, Arrays and List - you will see very soon for what they are good. They are all taken from the java.util library, a standard library that is available with every JDK.
Every class name in Java starts with a capital letter (by convention - it will build with a small letter as well, but you should get used to this convention) - I "fixed" this in your code.
I added a 2-dimensional array List<List<String>> lines = new ArrayList<>(). This might look a little confusing at first, but what it means is that we create a variable lines that holds the results of our parsing. The List<String> syntax means, that we have a generic type List that has a type parameter String - in other words: a list of strings. The whole List<List<String>> means we have a list of lists of strings, a 2-dimensional string array.
With the lines.add(Arrays.asList(values)) in your while loop, we can add the lines that you parsed to this 2-dimensional array. Arrays.asList(values) transforms the String[] array into a List as we need it to be compatible to our List<List<...>> type. This allows your lines to have variable length.
The last lines I added simply print the content of 2-dimensional array and should give you a good example for how to access the values in this array. If you need further help for this construct, check the foreach loop documentation.
Given this as an input file (read_ex.csv):
value_1-1,value_1-2,value_1-3,value_1-4
value_2-1,value_2-2,value_2-3,value_2-4
value_3-1,value_3-2,value_3-3,value_3-4
value_4-1,value_4-2,value_4-3,value_4-4
value_5-1,value_5-2,value_5-3,value_5-4
The program will print the following output:
Line 1 Column 1: value_1-1
Line 1 Column 2: value_1-2
Line 1 Column 3: value_1-3
Line 1 Column 4: value_1-4
Line 2 Column 1: value_2-1
Line 2 Column 2: value_2-2
Line 2 Column 3: value_2-3
Line 2 Column 4: value_2-4
Line 3 Column 1: value_3-1
Line 3 Column 2: value_3-2
Line 3 Column 3: value_3-3
Line 3 Column 4: value_3-4
Line 4 Column 1: value_4-1
Line 4 Column 2: value_4-2
Line 4 Column 3: value_4-3
Line 4 Column 4: value_4-4
Line 5 Column 1: value_5-1
Line 5 Column 2: value_5-2
Line 5 Column 3: value_5-3
Line 5 Column 4: value_5-4
Hope this helps :)
I am new to java and wold be open to any method that reads a csv into a file that a beginner could understand.
Here is an existing solution for you from Apache Commons, the Apache Commons CSV project. See the Apache Commons CSV parser guide.
It is very easy to use out of the box.
Here is a basic worfklow:
Create a class that has the fields that "match" the columns of csv file.
Each row in your csv is an object of that class with properties corresponding to the fields in your csv. Use the library to get each field and store it in your object in a loop.
In your loop, you will store the object with the fields/properties read from the csv in the ArrayList
After the loop ends, your ArrayList will have elements that "matches" the rows in your csv file. You are free to access any of the rows/elements in the list.
If you are not familiar with how List and ArrayList works in Java, please refer to pretty much any Java tutorials online including the Oracle Tutorial.
Search Stackoverflow for hundreds of posts about using Commons CSV.
To parse csv file into an array use this following code.
const csv = require('csv-parser');
const fs = require('fs');
var csvData = [];
var apiNames = [];
fs.createReadStream("APIsName.csv")
.pipe(csv(['ID',"API"]))
.on('data', function (csvrow) {
csvData.push(csvrow);
})
.on('end', function () {
for (i = 0; i < 5; i++) {
console.log(csvData);
}
for(y=0;y<apiNames.length;y++){
console.log(apiNames[y].names);
}
});
Related
I have a .CSV file with rows for [ID], [NAME], [LASTNAME], [EMAIL], [GENDER]. There are 1000 entries.
Out of those five rows I have to:
Find the total of people on the list. (using a for loop?)
Show the first 10 names (name, lastname).
Show 3 RANDOM names.
Only display emails. (Doable with the current code)
Display the first letters of their last name.
Add a random number behind their last name.
Can someone make an example, please?
As a Java beginner I really can't seem to find an answer to this. I have searched everywhere and i think im going crazy.
I have imported the .csv file to my java eclipse, using the following code, currently it only displays the ID's.
package test;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class test111 {
public static void main(String[] args) {
String fileName="test.csv";
File file = new File(fileName);
try {
Scanner inputStream = new Scanner(file);
inputStream.next();
while (inputStream.hasNext()) {
String data = inputStream.next();
String[] values = data.split(",");
System.out.println(values[0]);
}
inputStream.close();
System.out.println("e");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
In order to take every value you have to do something like this:
int id = Integer.parseInt(values[0]);
String name = values[1];
String lastName = values[2];
String email = values[3];
String gender = values[4];
Yours is a lesson in why you shouldn't blindly copy code without reading it, researching it and understanding it.
Look at line 15 from your own code. What do you think is going on here?
String[] values = data.split(",");
You've read a line from your CSV file into a field called data and now you're calling the .split method with a comma as a parameter to break up that line into tokens wherever it finds a comma. Those tokens are being placed into the cells of an array called values.
Why are you only getting your ID attribute? Look at this line:
System.out.println(values[0]);
We just established that all tokens have been placed in an array called values. Let's look at the attribute key you provided:
[ID], [NAME], [LASTNAME], [EMAIL], [GENDER]
Hmm... if printing values[0] gives us the ID, I wonder what we'd get if we... oh, I don't know... maybe tried to print from a different element in the array?
Try:
System.out.println(values[1]);
System.out.println(values[2]);
System.out.println(values[3]);
System.out.println(values[4]);
See what you get.
Coding is about trying things in order to learn them. Knowledge doesn't magically become embedded in your head. To learn something, you have to practice repeatedly, and in doing so, you're going to make mistakes -- this is just how it goes. Don't give up so easily.
I have been trying to read my txt file into java and then splitting the two integer columns to then be saved into a list or array. I need these two numbers seperated because I will be uploading a second txt file in which I will have more numbers that I will need to add or substract from the first files columns.
So here is a sample of my txt files:
file 1:
0033 2000
2390 500
etc.
file 2:
0033 2 400
3829 1 3020
etc.
The first file has two columns and the second file has three columns
To be very honest I'm not good with java at all. So far I have only been able to read the files and print them as they are.
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
public class test {
public static void readlines(File f) throws IOException {
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
String line;
int NumberOfLines = 0;
while ((line = br.readLine()) != null) {
System.out.println(line);
NumberOfLines++;
}
System.out.println("Number of lines read: " + NumberOfLines);
br.close();
fr.close();
}
public static void main(String[] args) {
File f = new File("filename1");
File s = new File("filename2");
try {
readlines(f);
readlines(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I know that I should be splitting the data using .split("\t") since it's a tab but how can I save this into a column array so that I can later on in a different class add then together? Do I need to make two classes in which I read file1 and in the second file 2? Afterwards I do all my adding in the main class?
Any ideas will be nice here!! Sorry for asking basic stuff but switching from matlab to java is kind of difficult for me D:
What I'd do is to make the readlines(File f) method return an array. Arrays (in case you don't know) are lists or (commonly) similar elements. For example, in your case, that method would return a String array. split() method returns an array of String, where each element is one of the splitted elements. For example:
String[] splitted = "Hello World!".split(' ');
In this case, splitted would be: ["Hello", "World!"]
If you make readlines(File f) return an array with the splitted read content, all you have to do in your main (if you want to keep this "matrix" appereance) is to push the returned value into another Array.
I hope I explained it clear enough ^^
How do I read a .csv excel file with x number of rows and y number of columns, ignore irrelevant cells (things like names), then compute an average of the numbers in each column?
The Excel I have is something like this (, indicates new cell):
ID, week 1, week 2, week 3, .... , week 7
0 , 1 , 0.5 , 0 , , 1.2
1 , 0.5 , 1 , 0.5 , , 0.5
y , ......
so, how do I make it so it reads that kind of .csv file then computes an average in the format Week 1 = (Week 1 average), Week 2 = (week2 average) for all weeks?
Also am I correct in assuming I need to use a 2D Array for this?
Edit
Here's my code so far, it's very crude and I'm not sure if it does things properly yet:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ClassAverage {
public static void main(String[] args){
readFile2Array("attendance.csv");
}
public static double[][] readFile2Array(String fileName){
try {
int rowCount = 0;
int colCount = 0;
Scanner rc = new Scanner(new File("attendance.csv"));
while (rc.hasNextLine()) {
rowCount++;
rc.nextLine();
}
rc.close();
System.out.println(rowCount);
Scanner cc = new Scanner(new File("attendance.csv"));
while (cc.hasNext()) {
colCount++;
cc.next();
}
cc.close();
colCount = colCount/rowCount;
System.out.println(colCount);
Scanner sc = new Scanner(new File("attendance.csv"));
double[][] spreadSheet = new double[rowCount][colCount];
while (sc.hasNext()) {
for (int i=0; i<spreadSheet.length; ++i){
for (int j=0; j<spreadSheet[i].length; ++j){
spreadSheet[i][j] = Double.parseDouble(sc.next());
}
}
}
sc.close();
return spreadSheet;
} catch (FileNotFoundException e) {
System.out.println("File cannot be opened");
e.printStackTrace();
}
return null;
}
public static double weeklyAvg(double[][] a){
}
}
So a summary of what it's intended to do
readFile2Array: read the csv file and count the number of rows, then count the total number of cells, divide total number of cells by number of rows to find number of columns. Read again and put each cell into the correct place in a 2D array.
weeklyAvg: I haven't thought up a way to do this yet, but it's supposed to read the array column by column and compute an average for each column, then print out the result.
PS. I'm very new at Java so I have no idea what some suggestions mean so I'd really appreciate suggestions that are pure java based without addons and stuff (I'm not sure if that's what some people are suggesting even). I hope it's not too much to ask for (if it's even possible).
You can use a Java library to handle your CSV file. For example opencsv ( you can find the latest maven version here http://mvnrepository.com/artifact/com.opencsv/opencsv/3.5)
And then you can parse your file like this :
CSVReader reader = new CSVReader(new FileReader("PATH_TO_YOUR_FILE"));
String[] nextLine;
int counter = 0;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
System.out.println(nextLine[0] + nextLine[1]);
}
You have to ignore the header line, you can simply do this by incrementing a counter and skipping the zero value.
To compute the average you can use a hashmap where the key is the column header name (example week 1). Then you increment with the current line value and after the loop is completed you divide by the number of lines (don't forget to substract the ignored lines like header line)
To parse simple CSV files, it's pretty simple to just manually parse through it, as long as you know the format is the same throughout the file and it does not contain errors
Create a storage data structure for each column you wish to compute (use a LinkedList<String>)
Read through the CSV file line by line with a BufferedReader
Use String.split(',') on each line and add the specific columns in the returned array to the correct LinkedList
Loop through the LinkedLists at the end and compute your averages (using Double.parseDouble() to convert the Strings to doubles)
To make sure that the String you're attempting to parse is a double, you can either use a try-catch statement or use a regex. Check Java: how to check that a string is parsable to a double? for more information
I found the problem. Apparently, there were random spaces in some of the names in the csv file, which was causing breaks at the 257th entry, as well as several others later on. So, I just took out the spaces and everything works fine now. Thanks to all who tried to help.
I have this code that reads from a csv file, puts the values in String array, and prints them for me to see. It runs fine until it reaches the 257th member of the array (each member has 3 values: last name, first name, and birth year). Here is a functioning version of the code:
package testing.csv.files;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//.csv comma separated values
String fileName = "C:/Users/Owner/Desktop/Data.csv";
File file = new File(fileName); // TODO: read about File Names
try {
Scanner inputStream = new Scanner(file);
inputStream.next(); //Ignore first line of titles
while (inputStream.hasNext()){
String data = inputStream.next(); // gets a whole line
String[] values = data.split(",");
System.out.println(data);
}
inputStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Now, when I change the line
System.out.println(data);
To this:
System.out.println(values[2]);
What I expected to happen was for only the birth years (3rd column) to be printed for every person in the array. However, it only prints out until the 257th person's birth year (out of over 18,000), and gives me the following error message:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at testing.csv.files.Test.main(Test.java:22)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
The "java: 22" seems to be referring to the above snippet of code I posted above that I changed. I am not really sure what the problem is. If my syntax is wrong, why did it print at all? The only thing I can think of is that perhaps a string array can only handle 257 different people each with their own 3 values. If that were the case, then I would need some kind of larger version of string to hold all of my data. Has anyone encountered this problem before? Is the problem somewhere in my syntax and loop?
If there are only two things in the values array, then the highest location that you can index into is 1.
For arrays, you can only index into size - 1 spots; that is, if your array was size ten, you could index into a location 9, or more verbose: array[9].
Change your indexing statement to this:
System.out.println(values[1]);
You might want to see the 257th record in the csv file. Would the split method create three tokens for it? If it should result in less than three tokens and you try to print the third token by typing
System.out.println(values[2]);
you will get an ArrayIndexOutOfBoundsException.
Change:
String data = inputStream.next(); // next() can read the input only till the space
to:
String data = inputStream.nextLine(); // nextLine() reads input including space between the words
Also better way is to iterate the array instead acess through index may be particular line in csv not containing the third column.
In my program, it reads a file called datafile.txt... inside the datafile.txt is a random 3 lines of words. What my program does is reads the file the user types in and then they can type in a Line # and Word # and it will tell them the word that is in that location.. for example..
What is the file to read from?
datafile.txt
Please enter the line number and word number (the first line is 1).
2 2
The word is: the
My problem is that my program reads the 3 lines in the txt doc as 0, 1 ,2 and the words start from 0. So to read the first word in the first line they would have to type 0,0 instead of 1,1. What I am trying to do is make it work so they can type 1,1 instead of 0,0. Not sure what my problem is right now, here is my code....
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class readingFile {
/**
* #param args
* #throws IOException
* #throws validException
*/
public static void main(String[] args) throws IOException, checkException
{
System.out.println("Enter file name: " );
Scanner keyboard = new Scanner(System.in);
BufferedReader inputStream = null;
ArrayList<String> file = new ArrayList<String>();
String fileName = keyboard.next();
System.out.println ("The file " + fileName +
" has the following lines below: ");
System.out.println();
try
{
inputStream = new BufferedReader(new FileReader(fileName));
ArrayList<String> lines = new ArrayList<String>();
while(true)
{
String line = inputStream.readLine();
if(line ==null)
{
break;
}
Scanner itemnize = new Scanner(line);
while(itemnize.hasNext())
{
lines.add(itemnize.next());
}
lines.addAll(lines);
System.out.println(lines+"\n");
}
System.out.println("Please enter the line number and word number");
int index1 = keyboard.nextInt();
int index = keyboard.nextInt();
System.out.println("The word is: "+ lines.get(index));
}
catch(FileNotFoundException e)
{
System.out.println("Error opening the file " + fileName);
}
inputStream.close();
}
private static void checkValid(ArrayList<String> items, int index) throws checkException
{
throw new checkException("Not Found");
}
}
The obvious solution to adapt 1-based user input to 0-based internal representation is to subtract one at some point. Seeing that you don't even use index1, writing
lines.get(index - 1)
isn't going to solve your problem completely. But I guess you can take it from there, and do something similar for the word index.
As I assume you are just learning to program I will point out 3 areas of improvement
Much like how mathematics has BIDMAS which determines the order of evaluation of an expression Java and other program languages evaluate statements in a particulate way. This means within the Parentheses of a function you may include a statment instead of a variable or constant. This will be evaluated with the result (or return) been passed into the called function. This is why MvG says you can do lines.get(index - 1)
Not all exceptions you should consider and plan around will the compiler inform you about. For example in your code an invalid input for line number or word number is entered you will get a Runtime Exception (array index out of bound)
Naming of variables should be useful, you have index and index1. What's the difference? I assume from reading your code one should be the user selected index of the line number and the second should be the index of the word on said line. May I suggest requestedLineIndex and requestedWordIndex.
On a final note this is not a usual StackOverflow question hence why your question has been 'voted down'. If you are learning as part of a course is there a course forum or Virtual Learning Environment (VLE) you can post questions on? The support of your peers at the same level of learning tends to help with exploring the basics of a language.