opencsvのCSVWriterを使用して書き込まれたCSVファイルから次のようにバッチを作成しようとしています。CSVWriterwriter=new CSVWriter(new FileWriter(filePath + createFileName)、'、'、CSVWriter.DEFAULT_QUOTE_CHARACTER);
そして、BufferedReaderは書き込まれたファイルを読み取ります。Csvファイルが書き込まれていて、読み取り操作もうまくいくと思います。だから、これまでのところうまく機能しています。しかし、同じ操作を使用してCsvに書き込む特定のデータを選択すると、バッチの作成でエラーが発生します。「CSVの解析に失敗しました。エスケープされていない引用符が見つかりました。引用符付きの値は引用符内にある必要があります」という例外が発生し、アプリケーションが期待どおりに動作しないようになっています。
このエラーが発生した後、データに「」(二重引用符)または「(二重引用符)」記号が含まれているようです(データは「asdf」、「1.0」、「」、「def」の形式で表示されます。 ")。私の理解では、二重引用符を見つけるためにRegexを適用しようとしましたが、ファイルを調べた後、繰り返される二重引用符が含まれていないため、見つかりませんでした。私がたどったリンクは次のとおりです。CSVファイル内のエスケープされていない連続しない二重引用符を置き換えます
その後、コードで次を使用します。File tmpFile = File.createTempFile( "bulkAPIInsert"、 ".csv"); データを一時ファイルに保持してから削除します。
上記のコードを次のコードに置き換えた後、私はどういうわけか次の例外を処理しましたが、さらに「CSVの解析に失敗しました。開いた見積もりを閉じる前にEOFに到達しました」という別の例外が発生しました。ファイルtmpFile=new File( "bulkAPIInsert.csv");
アプリケーションのパフォーマンスの問題になるため、上記の回避策に従うべきではないと思います。
CSVReaderクラスを調べると、取得したものとまったく同じ例外を示すカスタム例外が定義されていることがわかりました。しかし、二重引用符(CSVファイルのセル値)内に二重引用符が見つかった場合に発生すると思います。リンクを次のように参照しました:https ://github.com/mulesoft/salesforce-connector/blob/master/src/main/java/com/sforce/async/CSVReader.java
誰かが私が間違っているところやこの問題の回避策を教えてもらえますか?
コードスニペットを次のように共有します: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.");}
}
BatchInfoのgetStateMessage()メソッドは、説明されているエラーメッセージを表示します。