33

I'm trying to get a csv file from http://download.finance.yahoo.com/d/quotes.csv?s=msft&f=sl1p2 then parse it so that I can get the price and the price changed into an object that sets both properties. Is there a way that I can do this with the android libraries?

Edit: Here's the current state of the union (not working):

HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpGet httpGet = new HttpGet(uri);
        HttpResponse response = httpClient.execute(httpGet, localContext);
        String result = "";

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

        String line = null;
        while ((line = reader.readLine()) != null){
              result += line + "\n";
              String[] RowData = result.split("\n");
              String name = RowData[0];
              String price = RowData[1];
              String change = RowData[2];

              stock.setPrice(Double.parseDouble(price));
              stock.setTicker(name);
              stock.setChange(change);
            }
locoboy
  • 38,002
  • 70
  • 184
  • 260

3 Answers3

52

Try something like this:

    //--- Suppose you have input stream `is` of your csv file then:

    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    try {
        String line;
        while ((line = reader.readLine()) != null) {
             String[] RowData = line.split(",");
             date = RowData[0];
             value = RowData[1];
            // do something with "data" and "value"
        }
    }
    catch (IOException ex) {
        // handle exception
    }
    finally {
        try {
            is.close();
        }
        catch (IOException e) {
            // handle exception
        }
    }

Hope this helps.

Avisek Chakraborty
  • 8,229
  • 10
  • 48
  • 76
Harry Joy
  • 58,650
  • 30
  • 162
  • 207
  • @Harry, thanks much. For some reason I can't find the split method within a BufferedReader. Is there a special library that you're using? – locoboy Mar 19 '11 at 07:12
  • @cfarm54: then you should try using [SrtingTokenizer](http://developer.android.com/reference/java/util/StringTokenizer.html) – Harry Joy Mar 19 '11 at 07:21
  • @Harry, thanks I'll look into it. Can you walk me through the logic of the while statement? I'm a bit confused on line = reader.readLine() – locoboy Mar 19 '11 at 07:25
  • 2
    @cfarm54: The while loop will read csv file line by line until there is no line to read. Any more explanation needed? – Harry Joy Mar 19 '11 at 07:27
  • @Harry yeah, I'm trying to test it out at the moment, but can't get it to work. I think i have the right input stream, just the parsing is the problem. – locoboy Mar 19 '11 at 07:35
  • This solution may work for canned csv, but for freeform csv I would like to recommend the solution by Profete, because the CSV parser proposed there takes care of escaping out csv as well. – user210504 Mar 19 '11 at 20:55
  • how would I use the parser he is suggesting? – locoboy Mar 19 '11 at 21:04
  • Edited a minor mistake- code should be line.split(","); not reader.split(","); – Avisek Chakraborty Oct 14 '11 at 09:47
  • 8
    -1. This would work only for trivial CSV files; using a proper CSV library would be a better option in the long run. – Lie Ryan Oct 16 '11 at 12:04
  • 4
    @Harry Joy You didnt consider quotation marks. It will fail for csv: 'val1,"val2-1,val2-2",val3' – Sazzad Hissain Khan Sep 03 '14 at 11:38
  • Failing when you have comma in the string – Alex Nov 28 '16 at 20:53
17

For the first part:

HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://download.finance.yahoo.com/d/quotes.csv?s=msft&f=sl1p2");
HttpResponse response = httpClient.execute(httpGet, localContext);
String result = "";

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

For the second part, Harry is right, just follow his code, or use some libraries: http://commons.apache.org/sandbox/csv/

CSVReader reader = new CSVReader(** Insert your Reader here **);
    String [] nextLine;
    while ((nextLine = reader.readNext()) != null) {
        // nextLine[] is an array of values from the line
        System.out.println(nextLine[0] + nextLine[1] + "etc...");
    }
Waza_Be
  • 39,407
  • 49
  • 186
  • 260
0

A better CSV parser handles quoted fields

    import android.content.Context;
    import android.widget.Toast;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;

    public class CSVReader {
        private class StringDArray {
            private String[] data=new String[0];
            private int used=0;
            public void add(String str) {
                if (used >= data.length){
                    int new_size= used+1;
                    String[] new_data=new String[new_size];
                    java.lang.System.arraycopy( data,0,new_data,0,used);
                    data=new_data;
                }
                data[used++] = str;
            }
            public int length(){
                return  used;
            }
            public String[] get_araay(){
                return data;
            }
        }
        private  Context context;
        public CSVReader(Context context){
            this.context=context;
        }
        public List read(InputStream inputStream){
            List resultList = new ArrayList();
            try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String csvLine;
                final char Separator = ',';
                final char Delimiter = '"';
                final char LF = '\n';
                final char CR = '\r';
                boolean quote_open = false;
                while ((csvLine = reader.readLine()) != null) {
                    //String[] row = csvLine.split(",");// simple way
                    StringDArray a=new StringDArray();
                    String token="";
                        csvLine+=Separator;
                    for(char c:csvLine.toCharArray()){
                        switch (c){
                            case LF: case CR:// not required as we are already read line
                                quote_open=false;
                                a.add(token);
                                token="";
                            break;
                            case Delimiter:
                                quote_open=!quote_open;
                            break;
                            case Separator:
                                if(quote_open==false){
                                    a.add(token);
                                    token="";
                                }else{
                                    token+=c;
                                }
                            break;
                            default:
                                token+=c;
                            break;
                        }
                    }
                    if(a.length()>0 ) {
                        if(resultList.size()>0){
                            String[] header_row =(String[]) resultList.get(0);
                            if(a.length()>=header_row.length) {
                                String[] row = a.get_araay();
                                resultList.add(row);
                            }
                        }else{
                            String[] row = a.get_araay();
                            resultList.add(row);//header row
                        }
                    }
                }
                inputStream.close();
            }catch (Exception e){
                Toast.makeText(context,"Error : " + e.getMessage(), Toast.LENGTH_LONG).show();
            }
            return resultList;
        }
    }

Usage

    File file=new File(path);
    CSVReader csvReader=new CSVReader(activity.this);
    List csv=csvReader.read( new FileInputStream(file));
    if(csv.size()>0){
        String[] header_row =(String[]) csv.get(0);
        if(header_row.length>1){
            String col1=header_row[0];
            String col2=header_row[1];
        }
    }

    Toast.makeText(activity.this,csv.size() + " rows", Toast.LENGTH_LONG).show();

Sample data used
ID,Name
1,Test Item 1
"2","Test Item 2"
"3","Test , Item 3"
4,Test Item 4

Joshy Francis
  • 340
  • 7
  • 13