读取csv文件(包含字符,整数和特殊符号)并从java

时间:2015-08-13 19:59:14

标签: java csv arraylist bufferedreader

请帮我解决这个代码...我正在打开一个csv文件,其内容如下所示,我正在尝试从中提取数字,但它显示异常....请帮助< / p>

import java.io.*;
import java.util.*;

public class FDS2 
{
   public static void main(String[] args) throws IOException
    {
     ArrayList<String> al1 = new ArrayList<String>();
     ArrayList<Integer> al2= new ArrayList<>();

    try
    {
        BufferedReader finp = new BufferedReader(new FileReader("ex3.csv"));
        String str ;
        String strarr[];

        while((str=finp.readLine())!=null)
        {
            strarr = str.split(",") ;

             for(int i=0;i<strarr.length;i++)
             {
                 al1.add(strarr[i]);
             }


             for(int i=0;i<al1.size();i++)
             {
                 if (Character.isDigit(al1.get(i).charAt(0))==false)//||(al1.get(i)==null))
                 {
                     al1.remove(i);
                 }
                 else
                 {
                    System.out.println(al1.get(i)); 
                 }
             }

             for(int i=0;i<al1.size();i++)
             {
                 al2.add(Integer.parseInt(al1.get(i)));
                 //System.out.println(b.get(i));
             }

        }    
    }

    catch(IOException e)
        {
            System.out.println(e);     
        }

     System.out.println(al2);  

    }   
}

我的csv文件就像:

before,after,
100,109,
93,125,(Highly unexpected!)
106,104,(No change)
115,101,

5 个答案:

答案 0 :(得分:1)

if (Character.isDigit(al1.get(i).charAt(0))==false)//||(al1.get(i)==null))
{
    al1.remove(i);
}

不判断你是如何尝试这样做的风格(我建议使用OpenCSV),但我相信你的错误是你要按索引删除元素,所以问题在于一旦您从列表中删除了第0个元素,a1.size()将为1,并且您的删除循环已经终止而不删除所有文本元素。

答案 1 :(得分:0)

如果您接受不重新发明轮子,我会推荐一个名为BeanIO的库,我在几个项目中成功使用它们,用于解析和验证。

答案 2 :(得分:0)

我曾经认为在解析CSV文件时使用split方法是最简单有效的。我强烈建议查找Apache Commons CSV。它使得更容易,并允许您完成您正在寻找的

答案 3 :(得分:0)

如果您需要的是如此简单,我会直接进行而无需额外的依赖。如果我正确地理解了你要做的事情,那么java8就是这样的:

Stream<String> lines = Files.lines(Paths.get("/path/to/file.csv"));

List<Integer> result = 
    lines.flatMap(l -> Arrays.stream(l.split(",")))
    .filter(this::isDigit)
    .map(Integer::parseInt)
    .collect(toList());

https://gist.github.com/alacambra/b77d80e19c30c477bcb3上的完整代码)

但是,代码上的问题不是csv,而是在完全扫描之前从数组中删除项目的事实。

for (int i = 0; i < al1.size(); i++) {
    if (Character.isDigit(al1.get(i).charAt(0)) == false)){

        al1.remove(i); <---- that's the error

    } else {
        System.out.println(al1.get(i));
    }        
}

答案 4 :(得分:0)

使用uniVocity-parsers为您执行此操作。它比apache commons快3倍,并且具有更多功能:

    String input = "before,after,\n" +
            "100,109,\n" +
            "93,125,(Highly unexpected!)\n" +
            "106,104,(No change)\n" +
            "115,101,";

    ObjectRowListProcessor rowProcessor = new ObjectRowListProcessor();
    rowProcessor.convertFields(Conversions.toInteger()).set("before", "after"); //converts the given columns to integer

    CsvParserSettings settings = new CsvParserSettings(); //many options here, check the tutorial
    settings.setRowProcessor(rowProcessor);
    settings.setHeaderExtractionEnabled(true); //we want to use the first row as the headers row

    settings.selectFields("after", "before"); // here I even switched the order of the fields

    //parse
    new CsvParser(settings).parse(new StringReader(input));

    //get the rows
    List<Object[]> rows = rowProcessor.getRows();
    for(Object[] row : rows){
        System.out.println(Arrays.toString(row));
    }

输出(重新排序的字段):

[109, 100]
[125, 93]
[104, 106]
[101, 115]

如果删除settings.selectFields行,则输出为:

[100, 109, null]
[93, 125, (Highly unexpected!)]
[106, 104, (No change)]
[115, 101, null]

披露:我是这个图书馆的作者。它是开源和免费的(Apache V2.0许可证)。