解析csv文件处理空值java

qkf9rpyu  于 12个月前  发布在  Java
关注(0)|答案(2)|浏览(138)

我是java新手,正在练习解析csv文件。我已经弄明白了如何解析和使用构造函数来创建示例。但是,我的csv文件中有空字符串,控制台只是将IllegalArgumentException: No enum constant抛出给我。
我提到了:

  1. enum valueOf IllegalArgumentException: No enum const class
  2. Parse CSV file in java, and delaing with empty values
    不幸的是,它不起作用。当涉及到Person和空Profession时,程序中断。我是否需要填充一些字符串,如“NONE”来匹配枚举,或者有什么方法可以处理这个问题?任何帮助或提示都非常感谢。
    以下是我的Profession示例:
public enum Profession {
    DOCTOR, CEO, CRIMINAL, HOMELESS, UNEMPLOYED, MUSICIAN, BOXER , UNKNOWN, NONE;
}

下面是我的csv文件的样子:

[0],    [1], [2],    [3]  ,    [4]    ,   [5]   ,  [6] ,   [7]  ,  [8] , [9]
class, gender, age, bodyType, profession, pregnant, isYou ,species, isPet, role
scenario:green,   ,         ,           ,         ,        ,      ,      ,
person, female, 24, average ,           , FALSE   ,        ,      ,      , passenger
animal, male  ,  4,         ,           , FALSE   ,        , dog  , TRUE , pedestrian
  .
  .

下面是解析代码:

try (BufferedReader csvReader = new BufferedReader(new FileReader(csvFile));) {
String headerLine = csvReader.readLine(); //get rid of header

while ((line = csvReader.readLine()) != null) { 
    csvContents.add(line);// add the line to the ArrayList      
}

for (String csvLine : csvContents) {

    // split by comma and remove redundant spaces
    String[] data = csvLine.split(",",-1); 
    System.out.println(data[1]);// IndexOutOfBound

    Character character = null;
    String clazz = data[0].toLowerCase();// cannot use word "class" as a variable

    if (clazz.startsWith("scenario"&& data.length == 1)) { 
        scenario = new Scenario();
        scenario.setLegalCrossing(clazz.endsWith("green"));
        continue;
    } else if ("person".equals(clazz)&& data.length == 10) {
        Profession professionEnum = Profession.valueOf(data[4].toUpperCase().trim());  
        Gender genderEnum = Gender.valueOf(data[1].toUpperCase().trim());
        BodyType bodyTypeEnum =BodyType.valueOf(data[3].toUpperCase().trim());

        person = new Person(Integer.parseInt(data[2]), professionEnum ,genderEnum , bodyTypeEnum , Boolean.parseBoolean(data[5]));
        person.setAsYou(Boolean.parseBoolean(data[6]));

    } else if ("animal".equals(clazz)) {
        Gender genderEnum = Gender.valueOf(data[1].toUpperCase().trim());
        BodyType bodyTypeEnum =BodyType.valueOf(data[3].toUpperCase().trim());

        animal = new Animal(Integer.parseInt(data[2]) , genderEnum , bodyTypeEnum, data[7]);
        animal.setIsPet(Boolean.parseBoolean(data[8]));
    }
} catch (someException e) {
  e.printStackTrace();
}

解析后的行看起来像:

scenario:green,,,,,,,,,
person,female,24,average,doctor,false,false,,,passenger
person,male,40,overweight,unknown,false,false,,,passenger
person,female,2,average,,false,false,,,passenger
person,male,82,average,,false,false,,,pedestrian
person,female,32,average,ceo,true,false,,,pedestrian
person,male,7,athletic,,false,false,,,pedestrian
animal,male,4,,,false,false,dog,true,pedestrian
scenario:red,,,,,,,,,
x0fgdtte

x0fgdtte1#

请按以下步骤操作:

final int NO_OF_FIELDS = 10;
for (String csvLine : csvContents) {

    // split by comma and remove redundant spaces
    String[] data = csvLine.split(",", -1);
    if (data.length == NO_OF_FIELDS) {// <---Add this check to avoid ArrayIndexOutOfBoundsException
        System.out.println(data[1]);

        Character character = null;
        String clazz = data[0].trim().toLowerCase();// <---Trim to get rid of leading and trailing space

        if (clazz.startsWith("scenario" && data.length == 1)) {
            // ...
        } else if ("person".equals(clazz) && data.length == 10) {
            // Handle the exception as shown below
            Profession professionEnum;
            try {
                professionEnum = Profession.valueOf(data[4].trim().toUpperCase());// <---First trim then apply
                                                                                    // toUpperCase()
            } catch (IllegalArgumentException e) {
                professionEnum = Profession.UNKNOWN;
            }

            // ...

        } else if ("animal".equals(clazz)) {
            // ...
        }
    }
}
8e2ybdfx

8e2ybdfx2#

如果你以后遇到了带引号的字符串标记的问题,那么你可以使用OpenCSV library或更多符合csv的读取器循环。请看这个例子。

List<String> tokens = new ArrayList<String>(32);
String line;
while( (line=fileReader.readLine())!=null) {
    line=line.trim();
    if(line.isEmpty()) continue;
    tokens.clear();
    if (parseCSVLine(tokens, line, ',')>0) {
        for(int idx=0; idx<tokens.size(); idx++)
            System.out.print("|"+tokens.get(idx));
        System.out.println("|");
    }
}

- - - - 
public static int parseCSVLine(List<String> tokens, String line, char delim) {
    // this handles quoted string and tuple "" escape values,
    // array string is returned as a ["drama","comedy"] string value, reader must split to sub tokens.
    // ABCD, "string value", "string "" escape value", "[""drama"",""comedy""]", DEFG       
    int count=0;
    line = line+delim;
    final int maxIdx = line.length()-1;
    int startIdx=0, endIdx=-1; // both inclusive index
    boolean inQuote=false;
    for(int idx=0; idx<=maxIdx; idx++) {
        char ch = line.charAt(idx);
        if(ch==delim && !inQuote) {
            count++;
            //if(line.charAt(startIdx)=='"') startIdx++; // drop leading and trailing " string delimiter
            //if(line.charAt(endIdx)=='"') endIdx--;                
            String value = startIdx<=endIdx ? line.substring(startIdx, endIdx+1).trim() : ""; // trim tokens
            value = value.replace("\"\"", "\""); // convert "" -> "
            tokens.add(value);
            startIdx=idx+1;
            //endIdx=startIdx-1; // use -1
            inQuote=false;
        } else if(ch=='"') {
            if(idx<maxIdx && line.charAt(idx+1)=='"') {
                endIdx+=2; // tuple "" inside the quoted string value
                idx++;
            } else if(!inQuote) {
                inQuote=true; // start quoted string
                startIdx=idx+1; // drop leading " from the token
                //endIdx=startIdx;
            } else {
                inQuote=false; // end quoted string
                endIdx=idx-1;                   
            }
        } else {
            endIdx=idx; // "increment" endIdx, inclusive index to the last char of token
        }           
    }       
    return count;
}

相关问题