【问题标题】:How to parse CSV file into an array in Android Studio如何在 Android Studio 中将 CSV 文件解析为数组
【发布时间】:2016-11-19 19:39:36
【问题描述】:

我想知道如何解析 CSV 文件并将内容存储到数组中。我的 csv 文件看起来像这样:

1,bulbasaur,1,7,69,64,1,1
2,ivysaur,2,10,130,142,2,1

我只想要名字,所以第二个字段。我想将 csv 中的所有这些项目存储到字符串的数组或数组列表中。

任何想法如何做到这一点?

任何帮助将不胜感激!

【问题讨论】:

    标签: java android arrays csv parsing


    【解决方案1】:

    将 CSV 文件放在 Android 中的什么位置 在“res”文件夹中创建一个名为“raw”的文件夹,并将 CSV 文件放入其中。

    如何读取 CSV 文件, 自从它的Android以来没有什么特别的。我们将使用我们的标准 Java 代码。最好使用我们自己的代码而不是使用 API。下面的类是一个读取 CSV 文件的实用程序,它可以在 Android 应用程序中使用。 我们将在哪个数组中存储 csv 文件的项目 在这些示例中,它是 scorelist arraylist 。

    public class CSVFile {
        InputStream inputStream;
    
        public CSVFile(InputStream inputStream){
            this.inputStream = inputStream;
        }
    
        public List read(){
            List resultList = new ArrayList();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            try {
                String csvLine;
                while ((csvLine = reader.readLine()) != null) {
                    String[] row = csvLine.split(",");
                    resultList.add(row);
                }
            }
            catch (IOException ex) {
                throw new RuntimeException("Error in reading CSV file: "+ex);
            }
            finally {
                try {
                    inputStream.close();
                }
                catch (IOException e) {
                    throw new RuntimeException("Error while closing input stream: "+e);
                }
            }
            return resultList;
        }
    }
    

    那么如何从“raw”文件夹中加载 CSV 文件并使用上述工具读取呢?

    InputStream inputStream = getResources().openRawResource(R.raw.stats);
    CSVFile csvFile = new CSVFile(inputStream);
    List scoreList = csvFile.read();
    

    MainActivity.java

    public class MainActivity extends Activity {
        private ListView listView;
        private ItemArrayAdapter itemArrayAdapter;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            listView = (ListView) findViewById(R.id.listView);
            itemArrayAdapter = new ItemArrayAdapter(getApplicationContext(), R.layout.item_layout);
    
            Parcelable state = listView.onSaveInstanceState();
            listView.setAdapter(itemArrayAdapter);
            listView.onRestoreInstanceState(state);
    
            InputStream inputStream = getResources().openRawResource(R.raw.stats);
            CSVFile csvFile = new CSVFile(inputStream);
            List scoreList = csvFile.read();
    
            for(String[] scoreData:scoreList ) {
                itemArrayAdapter.add(scoreData);
            }
        }
    }
    

    ItemArrayAdapter.java

    public class ItemArrayAdapter extends ArrayAdapter {
        private List scoreList = new ArrayList();
    
        static class ItemViewHolder {
            TextView name;
            TextView score;
        }
    
        public ItemArrayAdapter(Context context, int textViewResourceId) {
            super(context, textViewResourceId);
        }
    
        @Override
        public void add(String[] object) {
            scoreList.add(object);
            super.add(object);
        }
    
        @Override
        public int getCount() {
            return this.scoreList.size();
        }
    
        @Override
        public String[] getItem(int index) {
            return this.scoreList.get(index);
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row = convertView;
            ItemViewHolder viewHolder;
            if (row == null) {
                LayoutInflater inflater = (LayoutInflater) this.getContext().
                        getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = inflater.inflate(R.layout.item_layout, parent, false);
                viewHolder = new ItemViewHolder();
                viewHolder.name = (TextView) row.findViewById(R.id.name);
                viewHolder.score = (TextView) row.findViewById(R.id.score);
                row.setTag(viewHolder);
            } else {
                viewHolder = (ItemViewHolder)row.getTag();
            }
            String[] stat = getItem(position);
            viewHolder.name.setText(stat[0]);
            viewHolder.score.setText(stat[1]);
            return row;
        }
    }
    

    activity_mail.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.javapapers.android.csvfileread.app.MainActivity">
        <ListView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/listView"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp" />
    </RelativeLayout>
    

    item_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/name"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="20dp" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/score"
            android:layout_alignParentTop="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="20dp" />
    </RelativeLayout>
    

    完整的源代码可以参考这些链接javapapers.com/wp-content/uploads/2014/07/CSVFileRead.zip

    我认为这会有所帮助

    【讨论】:

    • 如果 ',' 嵌套在嵌套引号中,这会避免拆分字符串吗?
    • 公共类 CSVFile 放在哪里?在 mainactivity.java 中?
    • 我的 csv 文件非常大,在“scoreData”中只有 10-12 个第一行项目。 csv 文件没有新的行或内容,只是 ',' 分隔项目
    【解决方案2】:

    更好的 CSV 解析器处理引用字段

        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(File file){
                List resultList = new ArrayList();
                try{
                    InputStream inputStream= new FileInputStream(file);
                    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;
            }
        }
    

    用法

        File file=new File(path);
        CSVReader csvReader=new CSVReader(activity.this);
        List csv=csvReader.read(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();
    

    使用的样本数据
    身份证、姓名
    1、测试项目1
    "2","测试项目 2"
    "3","测试,第 3 项"
    4、测试项目4

    【讨论】:

      【解决方案3】:

      免责声明:我从未使用过 Android,但我知道 Java,所以希望一切都一样。

      话虽如此,你可以试试这样的。

      Scanner scanner = new Scanner(new File("file.csv"));
      ArrayList<String> pokemon = new ArrayList<>();
      while(scanner.hasNextLine()) {
          pokemon.add(scanner.nextLine().split(",")[1]);
      }
      scanner.close();
      

      【讨论】:

        【解决方案4】:

        Android 默认不创建 raw 文件夹。在项目的 res/raw 下创建 raw 文件夹。在其中复制您的 CSV 文件。将 CSV 文件的名称保持小写,并在询问时转换为文本格式。我的 CSV 文件名为 welldata.scv WellData - 它是带有 getter 和 setter 的模型类。 wellDataList 是存储数据的ArrayList。

        private void readData() {
        InputStream is = getResources().openRawResource(R.raw.welldata);
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(is, Charset.forName("UTF-8")));
        String line = "";
        try {
            while ((line = reader.readLine()) != null) {
               //set splitter
                String[] tokens = line.split(",");
        
                //read the data
                WellData wellData = new WellData();
                wellData.setOwner(tokens[0]);
                wellData.setApi(tokens[1]);
                wellData.setLongitude(tokens[2]);
                wellData.setLatitude(tokens[3]);
                wellData.setProperty(tokens[4]);
                wellData.setWellName(tokens[5]);
                wellDataList.add(wellData);
        
                Log.d("MainActivity" ,"Just Created " +wellData);
        
            }
        } catch (IOException e1) {
            Log.e("MainActivity", "Error" + line, e1);
            e1.printStackTrace();
        }
        

        } }

        【讨论】:

          【解决方案5】:

          我扩展了 Sharma 的答案,使核心类在 CSV 文件的各种条件下更加灵活。我更喜欢构建器设计模式来配置如何读取 CSV 文件。

          public class CSVFile {
              private static final Charset UTF8 = Charset.forName("UTF-8");
              private final static String DEFAULT_DELIMITER = ",";
          
              private InputStream inputStream;
              private Charset charset;
              private String delimiter;
              private boolean ignoreHead;
          
              public CSVFile(InputStream inputStream) {
                  this.inputStream = inputStream;
                  this.charset = UTF8;
                  this.delimiter = DEFAULT_DELIMITER;
                  this.ignoreHead = false;
              }
          
              public CSVFile setCharset(Charset charset) {
                  this.charset = charset;
                  return this;
              }
          
              public CSVFile setDelimiter(String delimiter) {
                  this.delimiter = delimiter;
                  return this;
              }
          
              public CSVFile ignoreHead() {
                  ignoreHead = true;
                  return this;
              }
          
              public List<String[]> read() {
                  boolean firstRow = true;
                  List<String[]> resultList = new ArrayList<>();
                  BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset));
                  try {
                      String csvLine;
                      while ((csvLine = reader.readLine()) != null) {
                          if (firstRow) {
                              firstRow = false;
          
                              if (ignoreHead) {
                                  continue;
                              }
                          }
          
                          String[] row = csvLine.split(delimiter);
                          resultList.add(row);
                      }
                  } catch (IOException ex) {
                      throw new RuntimeException("Error in reading CSV file: " + ex);
                  } finally {
                      try {
                          inputStream.close();
                      } catch (IOException e) {
                          throw new RuntimeException("Error while closing input stream: " + e);
                      }
                  }
                  return resultList;
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-10-19
            • 2019-06-27
            • 2012-12-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-05-08
            • 2023-03-23
            相关资源
            最近更新 更多