Java 从CSV创建批导致错误状态

Java 从CSV创建批导致错误状态,java,salesforce,apex-code,bulkloader,opencsv,Java,Salesforce,Apex Code,Bulkloader,Opencsv,我正在尝试从使用opencsv的CSVWriter编写的CSV文件中进行批处理,如下所示: CSVWriter writer=new CSVWriter(new FileWriter(filePath+createFileName),“,”,CSVWriter.DEFAULT_QUOTE_字符) 和BufferedReader来读取写入的文件。Csv文件已经写入,我认为读取操作也很顺利。到目前为止,效果良好。但是,当我选择使用相同的操作将特定数据写入Csv时,批的创建会出错。 出现异常,说明“未

我正在尝试从使用opencsv的CSVWriter编写的CSV文件中进行批处理,如下所示: CSVWriter writer=new CSVWriter(new FileWriter(filePath+createFileName),“,”,CSVWriter.DEFAULT_QUOTE_字符)

和BufferedReader来读取写入的文件。Csv文件已经写入,我认为读取操作也很顺利。到目前为止,效果良好。但是,当我选择使用相同的操作将特定数据写入Csv时,批的创建会出错。 出现异常,说明“未能解析CSV。找到未替换的引号。带有引号的值应位于引号内”,这使应用程序无法按预期方式运行

在经历了这个错误之后,数据中似乎出现了一些“”(双引号)或“(双引号)符号。(我以“asdf”、“1.0”、“”、“def”、“def”的形式保存了数据)。 据我所知,我试图应用正则表达式查找双引号,但找不到任何双引号,因为在检查文件后,它不包含重复的双引号。我遵循的链接是:

此后,在代码中,我使用:File tmpFile=File.createTempFile(“bulkAPIInsert”、“.csv”);将数据保存在临时文件中,然后将其删除

在用下面的代码替换了上面的代码之后,我以某种方式处理了即将出现的异常,但它进一步导致另一个异常,声明“未能解析CSV”。在关闭打开的报价前达到EOF”。 文件tmpFile=新文件(“bulkapinsert.csv”)

我不认为应该遵循上面的解决方法,因为这将是应用程序的性能问题

通过查看CSVReader类,我发现定义了一个自定义异常,说明了与我得到的异常完全相同的异常。但我认为当在某个双qoute(CSV文件的单元格值)中发现双引号时,就会出现这种情况。我将链接称为:

有人能告诉我哪里做错了,或者这个问题的解决方法吗

我将代码片段分享给您,如下所示: Method1然后调用Method2

    Method1: private List<BatchInfo> createBatchesFromCSVFile(RestConnection connection,
            JobInfo jobInfo, String csvFileName) throws Exception {
        List<BatchInfo> batchInfos = new ArrayList<BatchInfo>();
        BufferedReader rdr = new BufferedReader(new InputStreamReader(
                new FileInputStream(csvFileName)));

        // read the CSV header row
        String hdr = rdr.readLine();
        byte[] headerBytes = (hdr + "\n").getBytes("UTF-8");
        int headerBytesLength = headerBytes.length;
//      I was making use of the following code which I replaced with the next line of code.
//      File tmpFile = File.createTempFile("bulkAPIInsert", ".csv");
        File tmpFile = new File("bulkAPIInsert.csv");
        // Split the CSV file into multiple batches
        try {
            FileOutputStream tmpOut = new FileOutputStream(tmpFile);
            int maxBytesPerBatch = 10000000; // 10 million bytes per batch
            int maxRowsPerBatch = 10000; // 10 thousand rows per batch
            int currentBytes = 0;
            int currentLines = 0;
            String nextLine;

            while ((nextLine = rdr.readLine()) != null) {
                byte[] bytes = (nextLine + "\n").getBytes("UTF-8"); //TODO
                if (currentBytes + bytes.length > maxBytesPerBatch
                        || currentLines > maxRowsPerBatch) {
                    createBatch(tmpOut, tmpFile, batchInfos, connection, jobInfo);
                    currentBytes = 0;
                    currentLines = 0;
                }
                if (currentBytes == 0) {
                    tmpOut = new FileOutputStream(tmpFile);
                    tmpOut.write(headerBytes);
                    currentBytes = headerBytesLength;
                    currentLines = 1;
                }
                tmpOut.write(bytes);
                currentBytes += bytes.length;
                currentLines++;
            }

            if (currentLines > 1) {
                createBatch(tmpOut, tmpFile, batchInfos, connection, jobInfo);
            }
        } finally {
            if(!tmpFile.delete())
                tmpFile.deleteOnExit();
            rdr.close();
        }
        return batchInfos;
    }

/**
     * Wait for a job to complete by polling the Bulk API.
     */
    Method2: private void awaitCompletion(RestConnection connection, JobInfo job,
            List<BatchInfo> batchInfoList) throws AsyncApiException { 
        try{
            /****
            Some code
            **/
                BatchInfo[] statusList = connection.getBatchInfoList(job.getId())
                .getBatchInfo();
                for (BatchInfo b : statusList) {
                    if (b.getState() == BatchStateEnum.Completed) {
                        if (incomplete.remove(b.getId())) 
                            //Do Something
                    }
                    else if(b.getState() == BatchStateEnum.Failed){ 

                        System.out.println("Reason: "+b.getStateMessage()+".\n  " +
                                "Number of Records Processed: "+b.getNumberRecordsProcessed());
                        throw (new Exception(""));
                    }
                }
            }
        }catch(Exception ex){log.debug(" Exception occurred.");}
    }
Method1:private List createBatchesFromCSVFile(RestConnection、,
JobInfo JobInfo,字符串csvFileName)引发异常{
List batchInfos=new ArrayList();
BufferedReader rdr=新的BufferedReader(新的InputStreamReader(
新文件输入流(csvFileName));
//读取CSV标题行
字符串hdr=rdr.readLine();
字节[]头字节=(hdr+“\n”).getBytes(“UTF-8”);
int headerBytes长度=headerBytes.length;
//我正在使用下面的代码,我将其替换为下一行代码。
//文件tmpFile=File.createTempFile(“bulkapinsert”、“.csv”);
文件tmpFile=新文件(“bulkapinsert.csv”);
//将CSV文件拆分为多个批
试一试{
FileOutputStream tmpOut=新的FileOutputStream(tmpFile);
int maxBytesPerBatch=10000000;//每批1000万字节
int maxRowsPerBatch=10000;//每批10000行
int currentBytes=0;
int currentLines=0;
字符串下一行;
而((nextLine=rdr.readLine())!=null){
byte[]bytes=(nextLine+“\n”).getBytes(“UTF-8”);//TODO
如果(currentBytes+bytes.length>maxBytesPerBatch
||currentLines>maxRowsPerBatch){
createBatch(tmpOut、tmpFile、batchInfos、connection、jobInfo);
currentBytes=0;
电流线=0;
}
如果(currentBytes==0){
tmpOut=新文件输出流(tmpFile);
tmpOut.write(头字节);
currentBytes=头字节长度;
电流线=1;
}
tmpOut.write(字节);
currentBytes+=bytes.length;
currentLines++;
}
如果(当前线路>1){
createBatch(tmpOut、tmpFile、batchInfos、connection、jobInfo);
}
}最后{
如果(!tmpFile.delete())
tmpFile.deleteOnExit();
rdr.close();
}
返回批处理信息;
}
/**
*通过轮询批量API等待作业完成。
*/
方法2:私有连接完成(RestConnection连接、JobInfo作业、,
List batchInfoList)引发AsyncApiException{
试一试{
/****
一些代码
**/
BatchInfo[]statusList=connection.getBatchInfoList(job.getId())
.getBatchInfo();
用于(批次信息b:状态列表){
如果(b.getState()==BatchStateEnum.Completed){
if(不完整。删除(b.getId())
//做点什么
}
如果(b.getState()==BatchStateEnum.Failed){
System.out.println(“原因:+b.getStateMessage()+”)\n+
“处理的记录数:”+b.getNumberRecordsProcessed());
抛出(新异常(“”);
}
}
}
}catch(异常ex){log.debug(“发生异常”);}
}
BatchInfo的getStateMessage()方法给出了讨论过的错误消息。

谢谢“Hound Dog”,帮了我的忙

回答


通过删除每个单元格的换行符,问题已经得到解决。

我的建议是创建一个简单的示例(使用一些数据)来重现问题。如果要拆分CSV文件,请非常小心,不要嵌入换行符(多行记录)否则你会有麻烦的!你可能想试试看你的数据是否真的有问题。我尝试从底部删除一些csv记录,直到我删除该记录时,创建了一个批