使用opencsv(java)读取.csv文件时跳过空白行

时间:2015-01-22 11:58:00

标签: java arrays csv

大家好! 我的目标是让csv阅读器在解析文件时跳过空白行,基本上什么也不做,只给我带有至少一个值的行。 目前我有两种方法 - > 1st只是读取所有行作为List of Strings数组并返回它,2nd将结果转换为字符串列表列表,两者都是下面的:

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;

}

我的第一个想法是检查(在2&#39; nd方法中)数组的长度,如果它的0只是为了忽略它 - 这将是这样的:

for (String[] rowItemsArray :  allRows) {
            **if(rowItemArray.length == 0) continue;**
            List<String> rowItems = new ArrayList<String>();
            rowItems.addAll(Arrays.asList(rowItemsArray));
            allRowsAsLists.add(rowItems);

}  

不幸的是,由于即使行为空,它仍然会返回一个元素数组 - 实际上是空字符串,因此无法工作。检查单个字符串不是一个选项,因为有100多列,这是可变的。 请建议实现这一目标的最佳方法是什么。 感谢。

以这种方式排序:

    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;
    }

3 个答案:

答案 0 :(得分:6)

您可以检查长度和第一个元素。如果该行仅包含字段分隔符,则长度> 1。 1.如果该行包含单个space字符,则第一个元素不为空。

if (rowItemsArray.length == 1 && rowItemsArray[0].isEmpty()) {
    continue;
}

答案 1 :(得分:3)

对于opencsv 5.0,有一个API选项可以将CSV行直接读取到Bean中。

对于更喜欢使用“ CsvToBean”功能的用户,以下解决方案是使用CsvToBeanBuilder上的(已弃用的)#withFilter(..)方法跳过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();

更新:在opencsv 5.1版(2020年2月2日)中,根据功能请求#120,不推荐使用CsvToBeanFilter。

答案 2 :(得分:0)

修剪它们后,您可以汇总每行的所有字符串值。如果结果字符串为空,则任何单元格中都没有值。在这种情况下忽略该行 这样的事情:

private boolean onlyEmptyCells(ArrayList<String> check) {
    StringBuilder sb = new StringBuilder();
    for (String s : check) {
        sb.append(s.trim());
    }
    return sb.toString().isEmpty(); //<- ignore 'check' if this returns true
}