0

I am having an issue while parsing a CSV file. It is only 2 rows of data with a comma separating them. Row one is a date and row 2 is a value. The date field will always have dates in it but sometimes the value is blank (or null?). When it gets to the null value I get a StringIndexOutOfBoundsException and the app crashes. I am logging each loop and can see the data but as soon as I get to a null value it stops looping and gives the error. If there are no null values then it works perfect. Here is my code:

        BufferedReader buf = new BufferedReader(new StringReader(file));
        String line = null;
        while ((line = buf.readLine()) != null) {
            try {
                String date = null, value = null;
                String[] RowData = line.split(",");
                date = RowData[0];
                value = RowData[1]; (this is the row it crashes on)

This is what the CSV looks like:

2011-08-28 09:16,8.23

2011-08-28 09:15,8.24

2011-08-28 09:14,8.26

2011-08-28 09:13,8.34

2011-08-28 09:12,

2011-08-28 09:11,10.72

2011-08-28 09:10,

2011-08-28 09:09,

the value at 09:13 is the last thing in logcat before I get the error.

This fixed it:

                if(RowData.length == 2) {
                    date = RowData[0];
                    value = RowData[1];
                } else {
                    date = RowData[0];
                    value = "0";
                }

I wrote a 0 in the value field so later processes will not choke on the null value. Thanks for all your help guys!

5 Answers 5

2

You want to do this or something like it:

String date = null, value = null;
String[] RowData = line.split(",");
date = RowData[0];

if(RowData.length ==2)value = RowData[1]; (this is the row it crashes on)

Or some variation of it e.g. if(RowData.length < 2) dont attempt to read the value. Its a pretty standard thing - if you ask an array for an index of a value it doesn't have Java will crash.

Sign up to request clarification or add additional context in comments.

2 Comments

I've tried all kinds of variations and it still crashes. I've tried stuff like if(RowData.length < 2) {value = "0";} else {value = RowData[1];} As usual I'm probably missing something simple lol.
I had to put the if statement before the date = RowData[0]; Thanks!
2

Why write your own CSV parsing when you could use a library that has already been written which will do it for you? Perhaps OpenCSV would help you achieve your CSV parsing goal.

3 Comments

Because I don't want an entire library when a few lines a code does what I need. I just cant get it to skip null values.
Use ProGuard to strip out any unused classes at compile time.
I fixed it using a simple if statement. I just wasn't sure what to check. I was checking the string that I was trying to set instead of the entire RowData. Thanks for the suggestion anyways. I had looked into that a while back when i first wrote the code but I decided to just kill the loop after the first null field and dump the existing data to a DB. I finally got back around to it and now it is fixed :)
1

Check the length of RowData before you try to access it. It looks like split() is returning an array with a single object but you're trying to access the second object, which is indeed out of bounds.

1 Comment

I updated my question above to include the section of the CSV file that is causing the crash. The line is not null but the second object is sometimes. I have tried different variations of checking for null along with if statements but it always if there is nothing after the comma.
1
public class CityParser {
    DocumentBuilderFactory factory;
    DocumentBuilder builder;
    Document doc;

    Element ele;

    int mediaThumbnailCount;`enter code here`
    boolean urlflag;
    CityListBean objBean = null;

    Vector<CityListBean> vecCityList;

    public CityParser() {

    }

    public Vector<CityListBean> getCityData() {

        vecCityList = new Vector<CityListBean>();
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpContext localContext = new BasicHttpContext();
            HttpGet httpGet = new HttpGet(
                    "http://heresmyparty.com/cms/index.php?option=com_chronocontact&chronoformname=add_event_form_download");
            HttpResponse response = httpClient.execute(httpGet, localContext);
            // String result = "";

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    response.getEntity().getContent()));

            CSVReader csvreader = new CSVReader(reader);
            String[] nextLine;
            while ((nextLine = csvreader.readNext()) != null) {

                CityListBean objcitylist = new CityListBean();
                // nextLine[] is an array of values from the line
                objcitylist.setText_title(nextLine[5]);
                objcitylist.setText_host(nextLine[6]);
                objcitylist.setText_price(nextLine[7]);
                objcitylist.setDate(nextLine[8]);
                objcitylist.setText_venue(nextLine[11]);
                objcitylist.setAddress(nextLine[12]);
                objcitylist.setLatitude(nextLine[13]);
                objcitylist.setLongitude(nextLine[14]);
                objcitylist.setFile(nextLine[15]);
                objcitylist.setText_description(nextLine[16]);
                objcitylist.setCity(nextLine[17]);
                vecCityList.addElement(objcitylist);

            }


              /*for (int i = 0; i < vecCityList.size(); i++) { CityListBean
              objcity = (CityListBean) vecCityList.get(i);

              System.out.println("Cf_id : " + objcity.getCityName());
              System.out.println("-----------------------------------"); }*/


        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return vecCityList;
    }
}

==========================================================================================

public class CSVReader {

    private BufferedReader br;

    private boolean hasNext = true;

    private char separator;

    private char quotechar;

    private int skipLines;

    private boolean linesSkiped;


    public static final char DEFAULT_SEPARATOR = ',';

    public static final char DEFAULT_QUOTE_CHARACTER = '"';

    public static final int DEFAULT_SKIP_LINES = 0;

    public CSVReader(Reader reader) {
        this(reader, DEFAULT_SEPARATOR, DEFAULT_QUOTE_CHARACTER,
            DEFAULT_SKIP_LINES);
    }

    public CSVReader(Reader reader, char separator, char quotechar, int line) {
        this.br = new BufferedReader(reader);
        this.separator = separator;
        this.quotechar = quotechar;
        this.skipLines = line;
    }

    public String[] readNext() throws IOException {

        String nextLine = getNextLine();
        return hasNext ? parseLine(nextLine) : null;
    }

    private String getNextLine() throws IOException {
        if (!this.linesSkiped) {
            for (int i = 0; i < skipLines; i++) {
                br.readLine();
            }
            this.linesSkiped = true;
        }
        String nextLine = br.readLine();
        if (nextLine == null) {
            hasNext = false;
        }
        return hasNext ? nextLine : null;
    }

    private String[] parseLine(String nextLine) throws IOException {

        if (nextLine == null) {
            return null;
        }

        List<String> tokensOnThisLine = new ArrayList<String>();
        StringBuffer sb = new StringBuffer();
        boolean inQuotes = false;
        do {
                if (inQuotes) {
                // continuing a quoted section, reappend newline
                sb.append("\n");
                nextLine = getNextLine();
                if (nextLine == null)
                    break;
            }
            for (int i = 0; i < nextLine.length(); i++) {

                char c = nextLine.charAt(i);
                if (c == quotechar) {
                        // this gets complex... the quote may end a quoted block, or escape another quote.
                        // do a 1-char lookahead:
                        if( inQuotes  // we are in quotes, therefore there can be escaped quotes in here.
                            && nextLine.length() > (i+1)  // there is indeed another character to check.
                            && nextLine.charAt(i+1) == quotechar ){ // ..and that char. is a quote also.
                                // we have two quote chars in a row == one quote char, so consume them both and
                                // put one on the token. we do *not* exit the quoted text.
                                sb.append(nextLine.charAt(i+1));
                                i++;
                        }else{
                                inQuotes = !inQuotes;
                                // the tricky case of an embedded quote in the middle: a,bc"d"ef,g
                                if(i>2 //not on the begining of the line
                                                && nextLine.charAt(i-1) != this.separator //not at the begining of an escape sequence
                                                && nextLine.length()>(i+1) &&
                                                nextLine.charAt(i+1) != this.separator //not at the     end of an escape sequence
                                ){
                                        sb.append(c);
                                }
                        }
                } else if (c == separator && !inQuotes) {
                    tokensOnThisLine.add(sb.toString());
                    sb = new StringBuffer(); // start work on next token
                } else {
                    sb.append(c);
                }
            }
        } while (inQuotes);
        tokensOnThisLine.add(sb.toString());
        return (String[]) tokensOnThisLine.toArray(new String[0]);

    }

    public void close() throws IOException{
        br.close();
    }

}

Comments

0

Have you tried to check first

if (RowData[1]!=null) or possibly if (RowData[1]!="") 

I don't see why that would cause your app to crash though, it should just set value to null or ""

1 Comment

Thanks, I already fixed it but it was crashing because the part of the app that was causing it to actually crash would not accept null strings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.