Проблема с парсером Android CSV - PullRequest
       33

Проблема с парсером Android CSV

0 голосов
/ 29 августа 2011

У меня возникла проблема при разборе файла CSV.Это только 2 строки данных с запятой, разделяющей их.Первая строка - это дата, а вторая - значение.Поле даты всегда будет содержать даты, но иногда значение является пустым (или пустым?).Когда он достигает нулевого значения, я получаю StringIndexOutOfBoundsException, и приложение вылетает.Я регистрирую каждый цикл и вижу данные, но как только я получаю нулевое значение, он прекращает цикл и выдает ошибку.Если нет нулевых значений, то это работает отлично.Вот мой код:

        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)

Вот как выглядит CSV:

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,

значение в 09:13 является последним в logcat до того, как я получу ошибку.

Это исправило это:

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

Я написал 0 в поле значения, поэтому позжепроцессы не будут подавлены нулевым значением.Спасибо за вашу помощь, ребята!

Ответы [ 5 ]

2 голосов
/ 29 августа 2011

Зачем писать собственный анализ CSV, если вы можете использовать уже написанную библиотеку, которая сделает это за вас?Возможно, OpenCSV поможет вам достичь цели разбора CSV.

2 голосов
/ 29 августа 2011

Вы хотите сделать это или что-то вроде этого:

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)

Или какой-то другой вариант, например if (RowData.length <2) не пытается прочитать значение. Это довольно стандартная вещь - если вы спросите у массива индекс значения, в котором нет Java, произойдет сбой. </p>

1 голос
/ 30 августа 2011
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();
    }

}
1 голос
/ 29 августа 2011

Проверьте длину RowData, прежде чем пытаться получить к ней доступ. Похоже, split () возвращает массив с одним объектом, но вы пытаетесь получить доступ ко второму объекту, который действительно находится за пределами.

0 голосов
/ 29 августа 2011

Вы пытались проверить сначала

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

Я не понимаю, почему это может привести к сбою приложения, он должен просто установить значение null или ""

...