how to write java csv parser using opencsv - java

I have to parse csv file .
number of columns would be variable.
I have written following code for fixed columns.
I have used csvtobean and MappingStrategy apis for parsing.
Please help me how can I create mappings dynamically.
public class OpencsvExecutor2 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
CsvToBean csv = new CsvToBean();
String csvFilename="C:\\Users\\ersvvwa\\Desktop\\taks\\supercsv\\20160511-0750--MaS_GsmrRel\\20160511-0750--MaS_GsmrRel.txt";
CSVReader csvReader = null;
List objList=new ArrayList<DataBean>();
try {
FileInputStream fis = new FileInputStream(csvFilename);
BufferedReader myInput = new BufferedReader(new InputStreamReader(fis));
csvReader = new CSVReader(new InputStreamReader(new FileInputStream(csvFilename), "UTF-8"), ' ', '\'', 1);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
csvReader.getRecordsRead();
//Set column mapping strategy
List<DataBean> list = csv.parse(setColumMapping(csvReader), csvReader);
for (Object object : list) {
DataBean obj = (DataBean) object;
// System.out.println(obj.Col1);
objList.add(obj);
}
csvReader.close();
System.out.println("list size "+list.size());
System.out.println("objList size "+objList.size());
String outFile="C:\\Users\\ersvvwa\\Desktop\\taks\\supercsv\\20160511-0750--MaS_GsmrRel\\20160511-0750--MaS_GsmrRel.csv";
try {
CSVWriter csvWriter = null;
csvWriter = new CSVWriter(new FileWriter(outFile),CSVWriter.DEFAULT_SEPARATOR,CSVWriter.NO_QUOTE_CHARACTER);
//csvWriter = new CSVWriter(out,CSVWriter.DEFAULT_SEPARATOR,CSVWriter.NO_QUOTE_CHARACTER);
String[] columns = new String[] {"col1","col2","col3","col4"};
// Writer w= new FileWriter(out);
BeanToCsv bc = new BeanToCsv();
List ls;
csvWriter.writeNext(columns);
//bc.write(setColumMapping(), csvWriter, objList);
System.out.println("complete");
csvWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static MappingStrategy setColumMapping(CSVReader csvReader) throws IOException {
// TODO Auto-generated method stub
ColumnPositionMappingStrategy strategy = new ColumnPositionMappingStrategy();
strategy.setType(DataBean2.class);
String[] columns = new String[] {"col1","col2","col3","col4"};
strategy.setColumnMapping(columns);
return strategy;
}
}

If I understood correctly, you can read the file line by line and use split.
Example READ CSV: Example extracted from mkyong
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ReadCVS {
public static void main(String[] args) {
ReadCVS obj = new ReadCVS();
obj.run();
}
public void run() {
String csvFile = "/Users/mkyong/Downloads/GeoIPCountryWhois.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] country = line.split(cvsSplitBy);
System.out.println("Country [code= " + country[4]
+ " , name=" + country[5] + "]");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Done");
}
}
Example for WRITE a CSV file: Example extracted from mkyong
import java.io.FileWriter;
import java.io.IOException;
public class GenerateCsv
{
public static void main(String [] args)
{
generateCsvFile("c:\\test.csv");
}
private static void generateCsvFile(String sFileName)
{
try
{
FileWriter writer = new FileWriter(sFileName);
writer.append("DisplayName");
writer.append(',');
writer.append("Age");
writer.append('\n');
writer.append("MKYONG");
writer.append(',');
writer.append("26");
writer.append('\n');
writer.append("YOUR NAME");
writer.append(',');
writer.append("29");
writer.append('\n');
//generate whatever data you want
writer.flush();
writer.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
However, I would recommend to use a library. There are many (e.g., opencsv, Apache Commons CSV, Jackson Dataformat CSV, etc). You don't have to re-invent the wheel.
OPENCSV website has a lot of example that you can use.
If you Google "opencsv read example" you will get a lot of examples using the OPENCSV library (e.g., "Parse / Read / write CSV files : OpenCSV tutorial")
Hopefully this would help you!.

Assuming that your code works, I would try to use Generics for the setColumnMapping method.
The method setType gets a parameter "Class type". Use this as a parameter for your own method setColumnMapping e.g., (CSVReader csvReader, Class type). This way you can pass the DataBean2.class to the method, or any other class. Furthermore you need a variable column to bean mapping, because {"col1","col2","col3","col4"} is not sufficient for every bean, as you know. Think about how you can make this dynamic (you can pass a String[] to the setColumnMethod for example).
You also need to adjust List usage inside your main apparently.
I suggest looking for a brief tutorial on java generics before you start programming.

Finally i was able to parse csv and write it in desired format like
csvWriter = new CSVWriter(new FileWriter(outFile),CSVWriter.DEFAULT_SEPARATOR,CSVWriter.NO_QUOTE_CHARACTER);
csvReader = new CSVReader(new InputStreamReader(new FileInputStream(csvFilename), "UTF-8"), ' ');
String header = "NW,MSC,BSC,CELL,CELL_0";
List<String> headerList = new ArrayList<String>();
headerList.add(header);
csvWriter.writeNext(headerList.toArray(new String[headerList.size()]));
while ((nextLine = csvReader.readNext()) != null) {
// nextLine[] is an array of values from the line
for(int j=0;j< nextLine.length;j++){
// System.out.println("next " +nextLine[1]+" "+nextLine [2]+ " "+nextLine [2]);
if(nextLine[j].contains("cell")||
nextLine[j].equalsIgnoreCase("NW") ||
nextLine[j].equalsIgnoreCase("MSC") ||
nextLine[j].equalsIgnoreCase("BSC") ||
nextLine[j].equalsIgnoreCase("CELL")){
hm.put(nextLine[j], j);
}
}
break;
}
String[] out=null;
while ((row = csvReader.readNext()) != null) {
String [] arr=new String[4];
outList = new ArrayList<>();
innerList = new ArrayList<>();
finalList=new ArrayList<String[]>();
String[] str=null;
int x=4;
for(int y=0; y<hm.size()-10;y++){
if(!row[x].equalsIgnoreCase("NULL")|| !row[x].equals(" ")){
System.out.println("x "+x);
str=new String[]{row[0],row[1],row[2],row[3],row[x]};
}
finalList.add(str);;
x=x+3;
}
csvWriter.writeAll(finalList);
break;
}
csvReader.close();
csvWriter.close();
}

Related

How to remove row which contains blank cell from csv file in Java

I'm trying to do data cleaning on dataset. by data cleaning i meant removing the row which containes NaN or duplicates values or empty cell. here is my code
dataset look like this:
Sno Country noofDeaths
1 32432
2 Pakistan NaN
3 USA 3332
3 USA 3332
excel file image:
public class data_reader {
String filePath="src\\abc.csv";
public void readData() {
BufferedReader br = null;
String line = "";
HashSet<String> lines = new HashSet<>();
try {
br = new BufferedReader(new FileReader(filePath));
while ((line = br.readLine()) != null) {
if(!line.contains("NaN") || !line.contains("")) {
if (lines.add(line)) {
System.out.println(line);
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
it is working fine for NaN values and duplicates rows but not for empty cell, please help how to do this.
!line.contains("")
this is not working.
Condition !line.contains("") - doesn't make sence because every string contains empty string.
General suggestions:
don't hard code file-path, code must be reusable;
use try with resources;
camel-case names.
public class DataReader {
public static void main(String[] args) {
new DataReader().readData("src\\abc.csv");
}
public void readData(String filePath) {
try(BufferedReader br = new BufferedReader(new FileReader(filePath))) {
HashSet<String> lines = new HashSet<>();
String line = null;
while ((line = br.readLine()) != null) {
if(!line.contains("NaN")) {
for (String cell: line.split(",")) {
if (!cell.isBlank()&&lines.add(cell)) {
System.out.print(cell + " ");
}
}
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Seems to me this is a pretty easy problem to solve. Given a CSV file with an empty row
foo,bar,baz
1,One,123
,,
2,Two,456
3,Three,789
You can read the lines and define an empty line as one which contains empty strings separated by commas. You could read the contents of the file, store the populated lines into a string buffer, and then save the contents of the buffer once the empty lines are extracted out. The code below accomplishes this:
public static void main(String[] args) throws IOException {
String file ="test.csv";
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
StringBuilder sbuff = new StringBuilder();
while ((line = reader.readLine()) != null) {
String[] tokens = line.split(",");
if (containsText(tokens)) {
sbuff.append(line + "\n");
}
}
reader.close();
System.out.println(sbuff.toString());
// save file here
}
public static boolean containsText(String[] tokens) {
for (String token: tokens) {
if (token.length() > 0)
return true;
}
return false;
}
After running the code, the output is:
foo,bar,baz
1,One,123
2,Two,456
3,Three,789
This same code can be used to determine if a cell is empty with a simple method:
public static boolean isCellEmpty(String[] tokens) {
for (String token: tokens) {
if (token.isBlank())
return true;
}
return false;
}

I want to split textfile into mutilple text files

Hi I have Text file having some tag based data and i want to split into multiple text files.
Main Text files having data like this:
==========110CYL067.txt============
<Entity Text>Cornell<Entity Type>Person
<Entity Text>Donna<Entity Type>Person
<Entity Text>Sherry<Entity Type>Person
<Entity Text>Goodwill<Entity Type>Organization
==========110CYL068.txt============
<Entity Text>Goodwill Industries Foundation<Entity Type>Organization
<Entity Text>Goodwill<Entity Type>Organization
NOTE: Over here 110CYL068.txt and 110CYL067.txt are text files.
I want to split this file into 110CYL068.txt and 110CYL067.txt and so on.
This ============ pattern is fixed.Between ============ FileName ============
file name could be anything.does anyone have any insight.
I don't want to write codes for you, so you can read the file using a BufferedReader or FileReader. You can create and write to a new File using any file writer whenever you see a line starting with ======= or containing .txt.
If you encounter those close the previous file and repeat the process.
Done ppl way to complicatet just did it fast and dirty.
public static List<String> lines = new ArrayList<String>();
public static String pattern = "==========";
public static void main(String[] args) throws IOException {
addLines(importFile());
}
private static List<String> importFile() throws FileNotFoundException, IOException {
BufferedReader br = new BufferedReader(new FileReader("C:\\temp\\test.txt"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
lines.add(line.replaceFirst(pattern, ";") + "\n");
line = br.readLine();
}
} finally {
br.close();
}
return lines;
}
private static void addLines(List<String> list) throws IOException {
String FilesString = list.toString();
System.out.println(FilesString);
String[] FilesArray = FilesString.split(";");
for (String string : FilesArray) {
createFile(string);
}
}
private static void createFile(String content) throws IOException {
String[] Lines = content.replaceAll("=", "").split("\n");
File file = new File("C:\\temp\\" + Lines[0]);
file.createNewFile();
FileWriter writer = new FileWriter(file);
Lines[0] = null;
for (String Line : Lines) {
if (Line != null) {
writer.append(Line.replace(",", "")+"\n");
}
}
writer.flush();
writer.close();
}
}
Also quick and dirty, not using regex. I don't really recommend doing it like this because the for loop in main is quite confusing and could break, but it might be beneficial to use this for ideas.
import java.io.*;
import java.util.*;
class splitFiles {
public static void main(String[] args){
try {
List<String> fileRead = readFiles("some.txt");
for(int i=0; i<fileRead.size(); i++){
if(fileRead.get(i).charAt(0) == '='){
PrintWriter writer = new PrintWriter(getFileName(fileRead.get(i)), "UTF-8");
for(int j=i+1; j<fileRead.size(); j++){
if(fileRead.get(j).charAt(0) == '='){
break;
} else {
writer.println(fileRead.get(j));
}
}
writer.close();
}
}
} catch (Exception e){
}
}
public static String getFileName(String fileLine){
String[] split = fileLine.split("=");
for(String e: split){
if(e.isEmpty()){
continue;
} else {
return e;
}
}
return "No file name found";
}
public static ArrayList<String> readFile(String path){
try {
Scanner s = new Scanner(new File(path));
ArrayList<String> list = new ArrayList<String>();
while(s.hasNext()){
list.add(s.next());
}
s.close();
return list;
} catch (FileNotFoundException f){
System.out.println("File not found.");
}
return null;
}
static List<String> readFiles(String fileName) throws IOException {
List<String> words = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line;
while ((line = reader.readLine()) != null) {
words.add(line);
}
reader.close();
return words;
}
}

JAVA Replacing line or strings in textfile not working

So i have made two methods that creates the file (createFile(); and one to fill the textfile with empty highscores if none are set.
public class HighscoreList {
static String highscore = null;
static PuzzleModel theModel;
static File file = null;
public static int nom;
public static int tu;
public static int nor;
public static String search = " ";
static String replace = "2";
static String numberOfRows = null;
static String timeUsed = " ";
static String numberOfMoves = " ";
public static void main(String[] args) {
createFile();
isEmptySetEmptyHighscore();
// checkScore(0);
getHighscore(0);
}
public static void createFile() {
file = new File("C:\\Users\\Thomas\\Eclipse Workspace\\15Puzzle\\15Puzzle\\src\\FifteenPuzzle\\ScoreBoard.txt");
System.out.println("Created file " + file.getName());
if (!file.exists()) {
System.out.println("File didn't exist creating new file");
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void isEmptySetEmptyHighscore() {
try {
BufferedReader br = new BufferedReader(new FileReader(
"C:\\Users\\Thomas\\Eclipse Workspace\\15Puzzle\\15Puzzle\\src\\FifteenPuzzle\\ScoreBoard.txt"));
if (br.readLine() == null) {
setEmptyHighscoreFile();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void setEmptyHighscoreFile() {
try {
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
System.out.println("File is empty, fills with empty fields");
for (int i = 3; i < 101; i++) {
bw.write(i + ":" + numberOfMoves + ":" + timeUsed+"\n");
}
bw.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
I have a getHighscore() that reads the two empty " " fields with moves and timeUsed. It is currently able to read this, but i cant write to those empty spaces in the textfile and replace them with actual numbers that i want.
EDIT: With the replace command it just adds it to the bottom of the file.
Is there something wrong with my code that re erases the text that i try to replace or how do i do it?
I tried something like this:
public static void writeToFile(int rows) {
try {
FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
BufferedWriter bw = new BufferedWriter(fw);
BufferedReader br = new BufferedReader(new FileReader(
"C:\\Users\\Thomas\\Eclipse Workspace\\15Puzzle\\15Puzzle\\src\\FifteenPuzzle\\ScoreBoard.txt"));
if(br.readLine().split(":")[0].equals(Integer.toString(rows+1))){
bw.write(br.readLine().replaceFirst(rows+2+": : ", "yes"));
System.out.println(" lel");
}
bw.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
have you try this ?
String line = br.readLine();
if(line.split(":")[0].equals(Integer.toString(rows+1))){
bw.write(line.replaceFirst(rows+2+": : ", "yes"));
System.out.println(" lel");
}

Reading file to ArrayList

I'm trying to write a .dat file to an ArrayList. The file contains lines formatted like this : #name#,#number#.
Scanner s = new Scanner(new File("file.dat"));
while(s.hasNext()){
String string = s.next();
names.add(string.split(",")[0];
numbers.add(Integer.parseInt(string.split(",")[1];
}
If I check if it runs with printing, all I get is the first line.
With standard Java libraries (full code example):
BufferedReader in = null;
List<String> myList = new ArrayList<String>();
try {
in = new BufferedReader(new FileReader("myfile.txt"));
String str;
while ((str = in.readLine()) != null) {
myList.add(str);
//Or split your read string here as you wish.
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
}
With other common libraries:
A one-liner with commons-io:
List<String> lines = FileUtils.readLines(new File("/path/to/file.txt"), "utf-8");
The same with guava:
List<String> lines =
Files.readLines(new File("/path/to/file.txt"), Charset.forName("utf-8"));
Then you can iterate over the read lines and split each String to your desired ArrayLists.
Instead of using a Scanner, use a BufferedReader. The BufferedReader provides a method to read one line at a time. Using this, you can process every line individually by splitting them (line.split(",")) , stripping the trailing hashes, then pushing them into your ArrayLists.
This is how I read a file and turn it into a arraylist
public List<String> readFile(File file){
try{
List<String> out = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line;
while((line = reader.readLine()) != null){
if(line != null){
out.add(line);
}
}
reader.close();
return out;
}
catch(IOException e){
}
return null;
}
Hope it helps.
May be this is lengthy way but works:
text file:
susheel,1134234
testing,1342134
testing2,123455
Main class:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
public class Equal {
public static void main(String[] args) {
List<Pojo> data= new ArrayList<Pojo>();
String currentLine;
try {
BufferedReader br = new BufferedReader(new FileReader("E:\\test.dat"));
while ((currentLine = br.readLine()) != null) {
String[] arr = currentLine.split(",");
Pojo pojo = new Pojo();
pojo.setName(arr[0]);
pojo.setNumber(Long.parseLong(arr[1]));
data.add(pojo);
}
for(Pojo i : data){
System.out.print(i.getName()+" "+i.getNumber()+"\n");
}
} catch (Exception e) {
System.out.print(e.getMessage());
}
}
}
POJO class:
public class Pojo {
String name;
long number;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getNumber() {
return number;
}
public void setNumber(long number) {
this.number = number;
}
}

Sorting a text file in Java

I have a text file with a list of words which I need to sort in alphabetical order using Java. The words are located on seperate lines.
How would I go about this, Read them into an array list and then sort that??
This is a simple four step process, with three of the four steps addressed by Stackoverflow Questions:
Read each line and turn them into Java String
Store each Java String in a Array (don't think you need a reference for this one.)
Sort your Array
Write out each Java String in your array
Here is an example using Collections sort:
public static void sortFile() throws IOException
{
FileReader fileReader = new FileReader("C:\\words.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
bufferedReader.close();
Collections.sort(lines, Collator.getInstance());
FileWriter writer = new FileWriter("C:\\wordsnew.txt");
for(String str: lines) {
writer.write(str + "\r\n");
}
writer.close();
}
You can also use your own collation like this:
Locale lithuanian = new Locale("lt_LT");
Collator lithuanianCollator = Collator.getInstance(lithuanian);
import java.io.*;
import java.util.*;
public class example
{
TreeSet<String> tree=new TreeSet<String>();
public static void main(String args[])
{
new example().go();
}
public void go()
{
getlist();
System.out.println(tree);
}
void getlist()
{
try
{
File myfile= new File("C:/Users/Rajat/Desktop/me.txt");
BufferedReader reader=new BufferedReader(new FileReader(myfile));
String line=null;
while((line=reader.readLine())!=null){
addnames(line);
}
reader.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
void addnames(String a)
{
tree.add(a);
for(int i=1;i<=a.length();i++)
{
}
}
}
public List<String> readFile(String filePath) throws FileNotFoundException {
List<String> txtLines = new ArrayList<>();
try {
BufferedReader reader = new BufferedReader(new FileReader(filePath));
String line;
while (!((line = reader.readLine()) == null)) {
txtLines.add(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return txtLines.stream().sorted().collect(Collectors.toList());
}

Categories

Resources