I have a issue here. I know that you have write the code like this, but this line gives null
Even if I have a header. I understand if csvContainer
is null if the CSV file is empty, but it should not be null if csvContainer
has at least one row or a header.
Found out that this can be done this way.
public void newRow(String rowText) {
try {
CsvParser csvParser = csvReader.parse(file, StandardCharsets.UTF_8);
Collection<String[]> data = new ArrayList<>();
csvParser.nextRow(); // Need to call this to get the header
data.add((String[]) csvParser.getHeader().toArray()); // Add header
CsvRow csvRow;
while((csvRow = csvParser.nextRow()) != null)
data.add((String[]) csvRow.getFields().toArray()); // Add existing lines to data
data.add(rowText.split(delimiter)); // Add the new line to data with a new line
csvWriter.write(file, StandardCharsets.UTF_8, data); // Auto close
} catch (IOException e) {
dialogs.exception("Cannot add new rows", e);
}
}
FastCSV should have a method where to append text to files. I know that you have such method, but that will first remove all data, then fill.
It's a great library and I will use it with Deeplearning4j. But I wonder if you could make an interface so it would be easier to use?
Easier I mean by a programmer should not need to write this much code for null exceptions
package se.danielmartensson.tools;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.siegmar.fastcsv.reader.CsvContainer;
import de.siegmar.fastcsv.reader.CsvParser;
import de.siegmar.fastcsv.reader.CsvReader;
import de.siegmar.fastcsv.reader.CsvRow;
import de.siegmar.fastcsv.writer.CsvAppender;
import de.siegmar.fastcsv.writer.CsvWriter;
import javafx.scene.control.Alert.AlertType;
/**
* The reason why we are using FastCSV and not SQLite, is due to memory use.
* @author Daniel Mårtensson
*
*/
public class CSVHandler {
private Dialogs dialogs = new Dialogs();
private CsvReader csvReader;
private CsvWriter csvWriter;;
private File file;
private String delimiter;
/**
* Constructor
* @param fileHandler File handler object
* @param filePath Path to our file
* @param delimiter Separator "," or ";" etc.
* @param headers String that contains name of columns with delimiter as separator
*/
public CSVHandler(FileHandler fileHandler, String filePath, String delimiter, String headers) {
file = fileHandler.loadFile(filePath);
this.delimiter = delimiter;
csvWriter = new CsvWriter();
csvReader = new CsvReader();
csvReader.setFieldSeparator(delimiter.charAt(0));
csvWriter.setFieldSeparator(delimiter.charAt(0));
/*
* Check if file has 0 rows = empty
*/
if(getTotalRows() == 0)
newHeader(headers); // Write our header if we don't have one
csvReader.setContainsHeader(true);
}
/**
* Get a single cell
* @param row Row index
* @param header Header name
* @return String
*/
public String getCell(int row, String header) {
try {
CsvContainer csvContainer = csvReader.read(file, StandardCharsets.UTF_8);
int totalRows = csvContainer.getRowCount();
if(row > totalRows)
dialogs.alertDialog(AlertType.WARNING, "Index", "Index out of bounds: " + row + " > " + totalRows);
else
for (int i = 0; i < totalRows; i++)
if(i == row)
return csvContainer.getRow(i).getField(header); // Success!
return ""; // Nothing happens!
} catch (IOException | NullPointerException e) {
dialogs.exception("Cannot get cell. Returning empty string", e);
return ""; // Empty
}
}
/**
* Return a complete row
* @param row Row number that we want to return
* @return
*/
public List<String> getRow(int row) {
try {
CsvContainer csvContainer = csvReader.read(file, StandardCharsets.UTF_8);
return csvContainer.getRow(row).getFields();
}catch(IOException | NullPointerException e) {
dialogs.exception("Cannot get rows. Return List<String> = null", e);
return null;
}
}
/**
* Set one value to a single cell
* @param row Row number
* @param header Our string header
* @param cellValue Our value that we want to insert
*/
public void setCell(int row, String header, String cellValue) {
try {
/*
* Get total columns and get the current cell value in a row
*/
CsvContainer csvContainer = csvReader.read(file, StandardCharsets.UTF_8);
CsvRow csvRow = csvContainer.getRow(row);
String currentCell = csvRow.getField(header);
int totalColumns = csvContainer.getRow(row).getFields().size();
/*
* Search for column index by searching for a know cell value
*/
int columIndex = 0;
while(columIndex < totalColumns)
if(csvRow.getField(columIndex).equals(currentCell))
break;
else
columIndex++;
/*
* Insert cellValue in column and insert row in container
*/
csvRow.getFields().set(columIndex, cellValue);
csvContainer.getRows().set(row, csvRow); // TODO: Testa ta bort denna rad
/*
* Collect and write all
*/
writeAll(csvContainer);
} catch (IOException | NullPointerException e) {
dialogs.exception("Cannot set cell", e);
}
}
/**
* Replace a whole row
* @param row row number
* @param text text with delimiter separator
*/
public void replaceRow(int row, String text) {
try {
/*
* Replace all items in a row
*/
CsvContainer csvContainer = csvReader.read(file, StandardCharsets.UTF_8);
CsvRow csvRow = csvContainer.getRow(row);
String[] list = text.split(String.valueOf(delimiter));
int totalColumns = csvContainer.getRow(row).getFields().size();
if(list.length == totalColumns) {
for(int i = 0; i < list.length; i++)
csvRow.getFields().set(i, list[i]);
/*
* Insert row in container
*/
csvContainer.getRows().set(row, csvRow); // TODO: Testa ta bort denna rad
/*
* Collect and write all
*/
writeAll(csvContainer);
}else {
dialogs.alertDialog(AlertType.ERROR, "Insert", "Not same dimension as CSV file");
}
} catch (IOException | NullPointerException e) {
dialogs.exception("Cannot replace row", e);
}
}
/**
* Search for a cell value in a g
* @param cellValue The cell in form of a string
* @param header Name of the column
* @return boolean
*/
public boolean exist(String cellValue, String header) {
try {
CsvContainer csvContainer = csvReader.read(file, StandardCharsets.UTF_8);
if(csvContainer == null)
return false; // Nothing has been added, except the header
for(int i = 0; i < csvContainer.getRowCount(); i++)
if(cellValue.equals(csvContainer.getRow(i).getField(header)) == true)
return true; // Yes
return false; // Nope
} catch (IOException | NullPointerException e) {
dialogs.exception("Cannot check existens. Returning false", e);
return false;
}
}
/**
* Find on which row cellValue is on a header
* @param cellValue
* @param header
* @return int
*/
public int findRow(String cellValue, String header) {
try {
CsvContainer csvContainer = csvReader.read(file, StandardCharsets.UTF_8);
for(int i = 0; i < csvContainer.getRowCount(); i++)
if(cellValue.equals(csvContainer.getRow(i).getField(header)) == true)
return i; // Yes
return 0; // Nope
} catch (IOException | NullPointerException e) {
dialogs.exception("Cannot find row index. Returning 0", e);
return 0;
}
}
/**
* Delete the whole row at least if we got a row
* @param row row number
*/
public void deleteRow(int row) {
try {
/*
* Remove a selected row
*/
CsvContainer csvContainer = csvReader.read(file, StandardCharsets.UTF_8);
csvContainer.getRows().remove(row);
writeAll(csvContainer);
} catch (IOException | NullPointerException e) {
dialogs.exception("Cannot delete row", e);
}
}
/**
* Write all to the file
* @param csvContainer The CsvContainer object
* @throws IOException
*/
private void writeAll(CsvContainer csvContainer) throws IOException {
/*
* Collect and write all
*/
Collection<String[]> data = new ArrayList<>();
for(CsvRow csvRow : csvContainer.getRows())
data.add((String[]) csvRow.getFields().toArray());
csvWriter.write(file, StandardCharsets.UTF_8, data); // Auto close
}
/**
* Write a new header to the CSV file - This won't give us csvAppender == null if we have empty file
* @param rowText Enter the string
*/
public void newHeader(String rowText) {
try {
Collection<String[]> data = new ArrayList<>();
data.add(rowText.split(delimiter)); // Add the header data
csvWriter.write(file, StandardCharsets.UTF_8, data); // Auto close
} catch (IOException | NullPointerException e) {
dialogs.exception("Cannot write now row", e);
}
}
/**
* Create a new row
* @param rowText
*/
public void newRow(String rowText) {
try {
CsvParser csvParser = csvReader.parse(file, StandardCharsets.UTF_8);
Collection<String[]> data = new ArrayList<>();
CsvRow csvRow = csvParser.nextRow(); // Need to call this to get the header
data.add((String[]) csvParser.getHeader().toArray()); // Add header
data.add((String[]) csvRow.getFields().toArray()); // Add the row under the header
while((csvRow = csvParser.nextRow()) != null) {
data.add((String[]) csvRow.getFields().toArray()); // Add existing lines to data
}
data.add(rowText.split(delimiter)); // Add the new line to data with a new line
csvWriter.write(file, StandardCharsets.UTF_8, data); // Auto close
} catch (IOException e) {
dialogs.exception("Cannot add new rows", e);
}
}
/**
* Return total rows
* @return int total rows
*/
public int getTotalRows() {
try {
CsvContainer csvContainer = csvReader.read(file, StandardCharsets.UTF_8);
if(csvContainer == null)
return 0; // Null means no rows here
return csvContainer.getRowCount();
} catch (IOException e) {
dialogs.exception("Cannot find total rows. Returning 0", e);
return 0;
}
}
/**
* Return total columns, in this case, it's on row index 0
* @return int total columns
*/
public int getTotalColumns() {
try {
CsvContainer csvContainer = csvReader.read(file, StandardCharsets.UTF_8);
if(csvContainer == null)
return 0; // Null means no rows here
return csvContainer.getRow(0).getFields().size();
} catch (IOException e) {
dialogs.exception("Cannot find total columns. Returning 0.", e);
return 0;
}
}
}