gpt4 book ai didi

java - 尝试解析由 ( , ) 分隔并使用引号的 CSV 文件

转载 作者:行者123 更新时间:2023-11-29 02:32:05 27 4
gpt4 key购买 nike

我在网上找不到太多帮助。我有一个要解析的 CSV 文件。分隔符是一个逗号,但是如果它是字段的一部分,我希望忽略它,所以我使用引号。当我在我的领域没有逗号时,我的方法很有效。但是,当我尝试通过向其中一个字段添加逗号来尝试将其视为单个记录时,我收到 ArrayIndexOutOfBoundsException 错误。这是我的代码。我用 AsyncTask 运行它。您会注意到我插入了代码 - r.get(1); r.get(2); 这仅用于测试。 r.get(1) 是抛出错误的行

class ParseCsvTask extends AsyncTask<File, Void, Void>{

@Override
protected void onPreExecute() {
mProgressBar.setVisibility(View.VISIBLE);
}

@Override
protected Void doInBackground(File... files) {
BufferedReader reader = null;
CSVParser parser = null;


File file = files[0];

CSVFormat formatter = CSVFormat.RFC4180.withFirstRecordAsHeader();

try {
reader = new BufferedReader(new FileReader(file));

parser = CSVParser.parse(reader, formatter);

List<CSVRecord> list = parser.getRecords();

for (CSVRecord r : list) {
r.get(1);
r.get(2);
Competitor competitor = new Competitor(r.get(1), r.get(2));
if (!r.get(0).equals("")) {
competitor.setMemberNum(r.get(0));
}
if(!r.get(4).equals("")){
competitor.setEmail(r.get(4));
}
if(!r.get(5).equals("")){
competitor.setPhone(r.get(5));
}

switch (r.get(7)){
case "":
competitor.setAge(Competitor.Age.ADULT);
break;
case "Junior":
competitor.setAge(Competitor.Age.JUNIOR);
break;
case "Senior":
competitor.setAge(Competitor.Age.SENIOR);
break;
case "Super Senior":
competitor.setAge(Competitor.Age.SUPER_SENIOR);
break;
default:
break;
}

if(r.get(8).equals("")){
competitor.setLady(false);
} else {
competitor.setLady(true);
}

mImportedComps.add(competitor);

}

FileHelper.writeMasterCompetitorsFile(mContext, mImportedComps);

Intent intent = new Intent(mContext, MasterCompetitorListActivity.class);
startActivity(intent);

} catch (Exception e) {
e.printStackTrace();
Log.d("record", "what is going on");
} finally {
try {
assert parser != null;
parser.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}

return null;
}

@Override
protected void onPostExecute(Void aVoid) {
mProgressBar.setVisibility(View.INVISIBLE);
}
}

请记住:当我在记录中不使用逗号时效果很好。 “名字”工作正常,但如果记录显示“名字”,我会收到错误消息。另外,我正在使用 *org.apache.commons.csv*

有人建议我发布的这个问题可能与这篇文章重复:Apache commons CSV: quoted input doesn't work .这篇文章的错误是invalid char between encapsulated token and delimiter 而我的错误与数组索引越界有关,这清楚地表明我们正在处理不同的场景。我没有被告知分隔符之间有任何无效字符。我的情况有所不同

这是我捕获到此错误时调用的堆栈跟踪:

03-05 15:34:44.397 778-778/com.checkinsystems.ez_score D/ViewRootImpl@4ca832c[MasterCompetitorListActivity]: ViewPostImeInputStage processPointer 0
03-05 15:34:44.479 778-778/com.checkinsystems.ez_score D/ViewRootImpl@4ca832c[MasterCompetitorListActivity]: ViewPostImeInputStage processPointer 1
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: at org.apache.commons.csv.CSVRecord.get(CSVRecord.java:79)
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: at com.checkinsystems.ez_score.ImportMasterCompsFileFragment$ParseCsvTask.doInBackground(ImportMasterCompsFileFragment.java:186)
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: at com.checkinsystems.ez_score.ImportMasterCompsFileFragment$ParseCsvTask.doInBackground(ImportMasterCompsFileFragment.java:158)
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:304)
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score W/System.err: at java.lang.Thread.run(Thread.java:762)
03-05 15:34:44.550 778-825/com.checkinsystems.ez_score D/record: what is going on

所以我发现了为什么会抛出 ArrayIndexOutOfBounds 错误。我运行了代码:

for(CSVRecord  r : list){
Log.d("record", r.toString());
}

就在拿到名单之后。我注意到由于某种原因,我得到了一条空白记录,然后是正确的记录。换句话说,这种模式重复出现,我以某种方式获得的记录数量是我需要的两倍,但其他记录都是空白的,这就是我会遇到索引问题的原因。但我仍然不明白为什么我会收到这些空白记录。这是调用代码的 onClick 按钮:

@Override
public void onClick(View view) {

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()
+ "/" + mFileName.getText().toString());

new ParseCsvTask().execute(file);

}

这是一些 logcat 输出....我已经更改了数据以隐藏人们的信息:

03-05 16:25:40.223 13019-13633/com.checkinsystems.ez_score D/record: CSVRecord [comment=null, mapping={member=0, first name=1, last name=2, name=3, email=4, phone=5, squad=6, age=7, gender=8, division=9, power factor=10, class=11, special =12}, recordNumber=1, values=[]]
03-05 16:25:40.223 13019-13633/com.checkinsystems.ez_score D/record: CSVRecord [comment=null, mapping={member=0, first name=1, last name=2, name=3, email=4, phone=5, squad=6, age=7, gender=8, division=9, power factor=10, class=11, special =12}, recordNumber=2, values=[A9J41, Bob, Al,len, Bob Allen, bob@comcast.net, 5555555555, 7, , , Production, Minor, D, ]]
03-05 16:25:40.223 13019-13633/com.checkinsystems.ez_score D/record: CSVRecord [comment=null, mapping={member=0, first name=1, last name=2, name=3, email=4, phone=5, squad=6, age=7, gender=8, division=9, power factor=10, class=11, special =12}, recordNumber=3, values=[]]
03-05 16:25:40.223 13019-13633/com.checkinsystems.ez_score D/record: CSVRecord [comment=null, mapping={member=0, first name=1, last name=2, name=3, email=4, phone=5, squad=6, age=7, gender=8, division=9, power factor=10, class=11, special =12}, recordNumber=4, values=[TY912111, Fred , Jones , Fred Jones , fred@gmail.com, 5555555555, 5, , , Revolver, Minor, C, ]]

请记住,只有当我在第一条记录的姓氏中间添加逗号时才会发生这种情况。如果我去掉那个逗号,它就可以正常工作

最佳答案

我解决了!我使用的是依赖于 RFC4180 标准的格式化程序。这个标准默认是这样的:

withDelimiter(',')
withQuote('"')
withRecordSeparator("\r\n")
withIgnoreEmptyLines(false)

最后一个属性 withIgnoreEmptyLines 需要设置为 true,否则格式化程序会在每隔一条记录之后插入一条空白记录。我不太确定为什么在我的记录之间插入空白记录会成为一种标准,但我用这一行修复了它:

CSVFormat formatter = CSVFormat.RFC4180.withFirstRecordAsHeader()
.withIgnoreEmptyLines(true);

这就是为什么我得到 ArrayIndexOutOfBounds

我希望这对其他人有帮助。感谢大家帮我解决这个问题

关于java - 尝试解析由 ( , ) 分隔并使用引号的 CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49118406/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com