You should use the excellent OpenCSV for reading and writing CSV files. To adapt your example to use the library it would look like this:
public class ParseCSV {
public static void main(String[] args) {
try {
//csv file containing data
String strFile = "C:/Users/rsaluja/CMS_Evaluation/Drupal_12_08_27.csv";
CSVReader reader = new CSVReader(new FileReader(strFile));
String [] nextLine;
int lineNumber = 0;
while ((nextLine = reader.readNext()) != null) {
lineNumber++;
System.out.println("Line # " + lineNumber);
// nextLine[] is an array of values from the line
System.out.println(nextLine[4] + "etc...");
}
}
}
}
Answer from Jason Sperske on Stack OverflowYou should use the excellent OpenCSV for reading and writing CSV files. To adapt your example to use the library it would look like this:
public class ParseCSV {
public static void main(String[] args) {
try {
//csv file containing data
String strFile = "C:/Users/rsaluja/CMS_Evaluation/Drupal_12_08_27.csv";
CSVReader reader = new CSVReader(new FileReader(strFile));
String [] nextLine;
int lineNumber = 0;
while ((nextLine = reader.readNext()) != null) {
lineNumber++;
System.out.println("Line # " + lineNumber);
// nextLine[] is an array of values from the line
System.out.println(nextLine[4] + "etc...");
}
}
}
}
Reading a CSV file in very simple and common in Java. You actually don't require to load any extra third party library to do this for you. CSV (comma separated value) file is just a normal plain-text file, store data in column by column, and split it by a separator (e.g comma ",").
In order to read specific columns from the CSV file, there are several ways. Simplest of all is as below:
Code to read CSV without any 3rd party library
BufferedReader br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] cols = line.split(cvsSplitBy);
System.out.println("Coulmn 4= " + cols[4] + " , Column 5=" + cols[5]);
}
If you notice, nothing special is performed here. It is just reading a text file, and spitting it by a separator – ",".
Consider an extract from legacy country CSV data at GeoLite Free Downloadable Databases
"1.0.0.0","1.0.0.255","16777216","16777471","AU","Australia"
"1.0.1.0","1.0.3.255","16777472","16778239","CN","China"
"1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia"
"1.0.8.0","1.0.15.255","16779264","16781311","CN","China"
"1.0.16.0","1.0.31.255","16781312","16785407","JP","Japan"
"1.0.32.0","1.0.63.255","16785408","16793599","CN","China"
"1.0.64.0","1.0.127.255","16793600","16809983","JP","Japan"
"1.0.128.0","1.0.255.255","16809984","16842751","TH","Thailand"
Above code will output as below:
Column 4= "AU" , Column 5="Australia"
Column 4= "CN" , Column 5="China"
Column 4= "AU" , Column 5="Australia"
Column 4= "CN" , Column 5="China"
Column 4= "JP" , Column 5="Japan"
Column 4= "CN" , Column 5="China"
Column 4= "JP" , Column 5="Japan"
Column 4= "TH" , Column 5="Thailand"
You can, in fact, put the columns in a Map and then get the values simply by using the key.
Shishir
Read column wise in csv file using java
java - How to read specific columns from CSV file? - Stack Overflow
iteration - How to read a specific column of a row from a csv file in java - Stack Overflow
Reading a column from CSV file using JAVA - Stack Overflow
Completing your code:
File file = new File("Filename.csv");
List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
for (String line : lines) {
String[] array = line.split(";");
System.out.println(array[0]+" "+array[array.length-1]);
}
You will notice that I changed the comma to a semi-colon as the split separator and added a bit to the println, which will be the last item in your split array.
I hope it helps.
String filename = "matches.csv";
File file = new File(filename);
try {
Scanner sc = new Scanner(file);
while (sc.hasNext()) {
String data = sc.next();
String[] values = data.split(",");
System.out.println(data);
}
sc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Read the input continuously within the loop so that the variable line is assigned a value other than the initial value
while ((line = br.readLine()) !=null) {
...
}
Aside: This problem has already been solved using CSV libraries such as OpenCSV. Here are examples for reading and writing CSV files
If you are using Java 7+, you may want to use NIO.2, e.g.:
❍ Code:
public static void main(String[] args) throws Exception {
File file = new File("test.csv");
List<String> lines = Files.readAllLines(file.toPath(),
StandardCharsets.UTF_8);
for (String line : lines) {
String[] array = line.split(",", -1);
System.out.println(array[0]);
}
}
❍ Output:
a
1RW
1RW
1RW
1RW
1RW
1RW
1R1W
1R1W
1R1W
I don't think you can read specific column.Better to read entire row using CSVParser or you can read CSV line by line and split it and get String array then you can get specific column but yes you need to read whole row gain.
Try it.
String fName = "C:\\Amit\\abc.csv";
String thisLine;
int count = 0;
FileInputStream fis = new FileInputStream(fName);
DataInputStream myInput = new DataInputStream(fis);
int i = 0;
while ((thisLine = myInput.readLine()) != null) {
String strar[] = thisLine.split(",");
System.out.println(strar[3]);
// Here column 2
}
}
By this way you can read specific column.
I had a similar problem in Objective C the other day, but this is how I solved it.
This method assumes you know the column number of the data you want. (I.E. if you want column 1 of 6)
Read all the rows into strings and append them into one.
Data sample: (columns 1 to 6)
1,2,3,4,5,6
13,45,63,29,10,8
11,62,5,20,13,2
String 1 = 1,2,3,4,5,6
String 2 = 13,45,63,29,10,8
String 3 = 11,62,5,20,13,2
Then you should get this:
String combined = 1,2,3,4,5,6,13,45,63,29,10,8,11,62,5,20,13,2 //add in the missing "," when you concatenate strings
Next you need to split the string into an array of all values.
Use code somewhat like this: (written off the top of my head so may be off.)
String[] values = combined.split(",");
Now you should have something like this:
Values = `"1", "2", "3", ... etc`
The last step is to loop through the entire array and modulo for whatever column you need:
//Remember that java numbers arrays starting with 0.
//The key here is that all remainder 0 items fall into the first column. All remainder 1 items fall into the second column. And so on.
for(int i = 0; i < values.length(); i++)
{
//Column1 - Column6 -> array lists of size values.length/number of columns
//In this case they need to be size values.length/6
if(i % 6 == 0)
column1.add(values[i]);
else if(i % 6 == 1)
column2.add(values[i]);
else if(i % 6 == 2)
column3.add(values[i]);
else if(i % 6 == 3)
column4.add(values[i]);
else if(i % 6 == 4)
column5.add(values[i]);
else if(i % 6 == 5)
column6.add(values[i]);
}
~~~~~~~~~~~~~~~~
Edit:
You added code to your question. Above I was saving them into memory. You just loop through and print them out. In your while loop, split each line separately into an array and then either hardcode the column number or modulo the length of the array as the index.
If your CSV file(s) always contains a Header Line which indicates the Table Column Names then it's just a matter of catching this line and splitting it so as to place those column names into a String Array (or collection, or whatever). The length of this array determines the amount of data expected to be available for each record data line. Once you have the Column Names it's gets relatively easy from there.
How you acquire your CSV file path and it's format type is obviously up to you but here is a general concept how to carry out the task at hand:
public static void readCsvToConsole(String csvFilePath, String csvDelimiter) {
String line; // To hold each valid data line.
String[] columnNames = new String[0]; // To hold Header names.
int dataLineCount = 0; // Count the file lines.
StringBuilder sb = new StringBuilder(); // Used to build the output String.
String ls = System.lineSeparator(); // Use System Line Seperator for output.
// 'Try With Resources' to auto-close the reader
try (BufferedReader br = new BufferedReader(new FileReader(csvFilePath))) {
while ((line = br.readLine()) != null) {
// Skip Blank Lines (if any).
if (line.trim().equals("")) {
continue;
}
dataLineCount++;
// Deal with the Header Line. Line 1 in most CSV files is the Header Line.
if (dataLineCount == 1) {
/* The Regular Expression used in the String#split()
method handles any delimiter/spacing situation.*/
columnNames = line.split("\\s{0,}" + csvDelimiter + "\\s{0,}");
continue; // Don't process this line anymore. Continue loop.
}
// Split the file data line into its respective columnar slot.
String[] lineParts = line.split("\\s{0,}" + csvDelimiter + "\\s{0,}");
/* Iterate through the Column Names and buld a String
using the column names and its' respective data along
with a line break after each Column/Data line. */
for (int i = 0; i < columnNames.length; i++) {
sb.append(columnNames[i]).append(": ").append(lineParts[i]).append(ls);
}
// Display the data record in Console.
System.out.println(sb.toString());
/* Clear the StringBuilder object to prepare for
a new string creation. */
sb.delete(0, sb.capacity());
}
}
// Trap these Exceptions
catch (FileNotFoundException ex) {
System.err.println(ex.getMessage());
}
catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
With this method you can have 1 to thousands of columns, it doesn't matter (not that you would ever have thousands of data columns in any given record but hey....you never know... lol). And to use this method:
// Read CSV To Console Window.
readCsvToConsole("test.csv", ",");
Here is some code that I recently worked on for an interview that might help: https://github.com/KemarCodes/ms3_csv/blob/master/src/main/java/CSVProcess.java
If you always have 3 attributes, I would read the first line of the csv and set values in an object that has three fields: attribute1, attribute2, and attribute3. I would create another class to hold the three values and read all the lines after, creating a new instance each time and reading them in an array list. To print I would just print the values in the attribute class each time alongside each set of values.
According to your input data example:
|HEADER 1| HEADER 2| HEADER 3|
|A|B|C|
|D| |F|
So you have a file composed from ha header line, where you have your column names, and the data.
To read the colimns name you need to parse the first row differently:
// field separator
String separator = ";";
//...
int i = 0;
Map<String, int> headers = new HashMap<>();
for (String line : lines) {
if (i == 0) {
String[] headLine = line.split(separator);
for (int j = 0; j < headLine.length; j++) {
headLine.put(headLine[j], j);
}
i++;
continue;
}
}
So you put each column name in your map and you save the index of the column.
The size of the map it is also the row len to check if you read all the expected fields.
Then you read the data:
int col1 = 1; // assign a valid column index
int fields = 0;
for (String line : lines) {
if (array[col1].equals("")) {
// System.out.println("Cell is blank");
break;
} else {
// System.out.println(array[col1].toString());
fields++;
}
}
if (fields < headers.size()) {
msg = "Invalid file";
// headers[fields] is the name of the column with the empty cell
}
In your example col1 is the index not the name of the column, but you never set it with a value, maybe this is one of the issues.
Below function will Read column name as parameter and output Valid if Column is Not empty and Invalid if column is empty
Input as in csv file
HEADER1;HEADER2;HEADER3;
A;;C;
D;E;F;
Solution:
public String fun(String col) throws IOException {
String[] array = null;
int Colx = -1; //Colx is Column index
File file = new File("test.csv");
List < String > lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8); //reads all lines
for (String line: lines) {
array = line.split(";", -1); //split each line to array
if (Colx != -1) { //Except first Row
if (array[Colx].equals("")) { // and only Empty columns
return "Invalid";
}
} else { //only for first row // finding index of column matched
for (String ar: array) {
Colx++;
if (ar.equalsIgnoreCase(col)) {
break;
}
}
}
}
return "Valid"; //if Everything went well
}