如何在 Android Studio 中将 CSV 文件解析为数组
Posted
技术标签:
【中文标题】如何在 Android Studio 中将 CSV 文件解析为数组【英文标题】:How to parse CSV file into an array in Android Studio 【发布时间】: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 中的所有这些项目存储到字符串的数组或数组列表中。
任何想法如何做到这一点?
任何帮助将不胜感激!
【问题讨论】:
【参考方案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_
android:layout_
tools:context="com.javapapers.android.csvfileread.app.MainActivity">
<ListView
android:layout_
android:layout_
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_
android:layout_>
<TextView
android:layout_
android:layout_
android:id="@+id/name"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="20dp" />
<TextView
android:layout_
android:layout_
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;
【讨论】:
以上是关于如何在 Android Studio 中将 CSV 文件解析为数组的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android Studio 中将 ListView 更改为 RecyclerView?
如何在 Android Studio Java 中将数组上传到 Firestore 数据
如何在 Android Studio 项目中将库添加到 Gradle 构建?