Good day everyone! My target is to make csv reader to skip the blank lines while parsing a file, do nothing basically, only get me the rows with at least one value. At the moment I have two methods -> 1st is just reading all rows as List of Strings array and returns it, 2nd converts the result into List of Lists of Strings, both are bellow:
private List<String[]> readCSVFile(File filename) throws IOException {
CSVReader reader = new CSVReader(new FileReader(filename));
List<String[]> allRows = reader.readAll();
return allRows;
}
public List<List<String>> readFile(File filename) throws IOException {
List<String[]> allRows = readCSVFile(filename);
List<List<String>> allRowsAsLists = new ArrayList<List<String>>();
for (String[] rowItemsArray : allRows) {
List<String> rowItems = new ArrayList<String>();
rowItems.addAll(Arrays.asList(rowItemsArray));
allRowsAsLists.add(rowItems);
}
return allRowsAsLists;
}
My first thought was to check (in the 2'nd method) the length of an array if its 0 just to ignore it - which would be something like this:
for (String[] rowItemsArray : allRows) {
**if(rowItemArray.length == 0) continue;**
List<String> rowItems = new ArrayList<String>();
rowItems.addAll(Arrays.asList(rowItemsArray));
allRowsAsLists.add(rowItems);
}
Unfortunately that didn't work for the reason that even if the row is blank it still returns an array of elements - empty Strings in fact. Checking an individual String is not an option as there are 100+ columns and this is variable. Please suggest what’s the best way to achieve this. Thanks.
Sorted it out this way:
public List<List<String>> readFile(File filename) throws IOException {
List<String[]> allRows = readCSVFile(filename, includeHeaders, trimWhitespacesInFieldValues);
List<List<String>> allRowsAsLists = new ArrayList<List<String>>();
for (String[] rowItemsArray : allRows) {
**if(allValuesInRowAreEmpty(rowItemsArray)) continue;**
List<String> rowItems = new ArrayList<String>();
rowItems.addAll(Arrays.asList(rowItemsArray));
allRowsAsLists.add(rowItems);
}
return allRowsAsLists;
}
private boolean allValuesInRowAreEmpty(String[] row) {
boolean returnValue = true;
for (String s : row) {
if (s.length() != 0) {
returnValue = false;
}
}
return returnValue;
}
You could check the length and the first element. If the line contains only a field separator then the lenght > 1. If the line contains a single space
character then the first element is not empty.
if (rowItemsArray.length == 1 && rowItemsArray[0].isEmpty()) {
continue;
}
For opencsv 5.0 there is an API-option to read CSV lines directly into a Bean.
For people who prefer using the "CsvToBean" feature, the following solution is using the (sadly deprecated) #withFilter(..) method on CsvToBeanBuilder to skip blank lines in the Inputstream:
InputStream inputStream; // provided
List<MyBean> data = new CsvToBeanBuilder(new BufferedReader(new InputStreamReader(inputStream)))
.withType(MyBean.class)
.withFilter(new CsvToBeanFilter() {
/*
* This filter ignores empty lines from the input
*/
@Override
public boolean allowLine(String[] strings) {
for (String one : strings) {
if (one != null && one.length() > 0) {
return true;
}
}
return false;
}
}).build().parse();
Update: With opencsv Release 5.1 (dated 2/2/2020), CsvToBeanFilter got undeprecated as per feature request #120.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With