添加记录时如何指示 CSVPrinter 不写入 header 行?
How do I instruct CSVPrinter to not write a header line when adding a record?
我有一个 CSV 文件,它是由我正在编写的程序以外的程序创建的,因此我无法更改 header。文件的 header 是 ControllerID,Event,Number,ReaderID,Timestamp,TransactionID,
。我已经为 CSVPrinter
指定了相同的 headers,我用它来将一行插入到同一个 CSV 中。但是,当打印机添加一条记录时,它会在新记录之前添加一个 header 行,如下所示:
0,1,2688229830,3,2018-09-03 13:54,63
ControllerID,Event,Number,ReaderID,Timestamp,TransactionID
0,1,4900920,2,2018-09-03,15:15,176492
有问题的代码如下所示:
/* Add an entry to the TransactionLog CSV */
private static boolean logTransaction (
int cid, int rid, boolean freeExit, long tsMS, long accNum, String reason
) {
boolean added = false;
int evt = freeExit ? 8 : 1;
File transactLog = new File(Locations.getDatabaseDir(), "TransactLog.csv"),
CSVFormat shortFormat = CSVFormat.DEFAULT.withQuote(null)
.withAllowMissingColumnNames(true)/*.withTrailingDelimiter(true)*/
.withHeader(Transaction.getHeader(false));
// Attempt to read the last transaction ID and add 1 to it, to be used as ID of new transaction
try (
CSVParser shortParser = new CSVParser(new FileReader(transactLog), shortFormat);
CSVPrinter shortWriter = new CSVPrinter(new FileWriter(transactLog, true), shortFormat);
) {
// read in all the current records, getting the transactionID of the last record
List<CSVRecord> shortRecords = shortParser.getRecords();
int newTransId = 1;
if (!shortRecords.isEmpty()) {
CSVRecord last = shortRecords.get(shortRecords.size() - 1);
String lastTransactionId = last.get("TransactionID");
// add one to last transaction ID
try {
newTransId = Integer.parseInt(lastTransactionId) + 1;
} catch (IllegalArgumentException IAEx) {
newTransId = shortRecords.size() + 1;
LOGGER.warn("Failed to determine last transaction ID from CSV ("
+ lastTransactionId + "); setting to recordCount (" + newTransId + ") ..."
);
}
}
// write the new transaction record
Transaction t = new Transaction(cid, evt, accNum, rid, tsMS, newTransId, reason);
List<String> tValues = t.asList(false), fValues = t.asList(true);
shortWriter.printRecord(tValues);
shortWriter.flush();
added = true;
} catch (IOException IOEx) {
added = false;
LOGGER.error(Util.getErrorTrace(
"Failed to write transaction to \"" + transactLog.getAbsolutePath() + "\" CSV", IOEx
));
}
return added;
}
省略了事务POJO的代码,因为它与问题无关。
如何防止 CSVPrinter
在输出行之前输出 header 行? (CSV 文件已包含 header 行。)
为了不输出header行,需要在CSVPrinter
使用的CSVFormat
实例中添加.withSkipHeaderRecord(true)
,如下:
CSVFormat skipFormat = CSVFormat.DEFAULT.withQuote(null)
.withAllowMissingColumnNames(true).withTrailingDelimiter(true)
.withHeader(Transaction.getHeader(false))
.withSkipHeaderRecord(true).withIgnoreEmptyLines(true);
对 .withIgnoreEmptyLines(true)
的调用是可选的。包含它是为了不保留 empty/blank 行。
注意:如果要输出header行作为文件的第一行,创建时,可以将.withSkipHeaderRecord(true)
改为.withSkipHeaderRecord(csvFile.exists())
。这是有效的,因为文件在创建之前不存在,但在下一次写入记录时存在。
我有一个 CSV 文件,它是由我正在编写的程序以外的程序创建的,因此我无法更改 header。文件的 header 是 ControllerID,Event,Number,ReaderID,Timestamp,TransactionID,
。我已经为 CSVPrinter
指定了相同的 headers,我用它来将一行插入到同一个 CSV 中。但是,当打印机添加一条记录时,它会在新记录之前添加一个 header 行,如下所示:
0,1,2688229830,3,2018-09-03 13:54,63
ControllerID,Event,Number,ReaderID,Timestamp,TransactionID
0,1,4900920,2,2018-09-03,15:15,176492
有问题的代码如下所示:
/* Add an entry to the TransactionLog CSV */
private static boolean logTransaction (
int cid, int rid, boolean freeExit, long tsMS, long accNum, String reason
) {
boolean added = false;
int evt = freeExit ? 8 : 1;
File transactLog = new File(Locations.getDatabaseDir(), "TransactLog.csv"),
CSVFormat shortFormat = CSVFormat.DEFAULT.withQuote(null)
.withAllowMissingColumnNames(true)/*.withTrailingDelimiter(true)*/
.withHeader(Transaction.getHeader(false));
// Attempt to read the last transaction ID and add 1 to it, to be used as ID of new transaction
try (
CSVParser shortParser = new CSVParser(new FileReader(transactLog), shortFormat);
CSVPrinter shortWriter = new CSVPrinter(new FileWriter(transactLog, true), shortFormat);
) {
// read in all the current records, getting the transactionID of the last record
List<CSVRecord> shortRecords = shortParser.getRecords();
int newTransId = 1;
if (!shortRecords.isEmpty()) {
CSVRecord last = shortRecords.get(shortRecords.size() - 1);
String lastTransactionId = last.get("TransactionID");
// add one to last transaction ID
try {
newTransId = Integer.parseInt(lastTransactionId) + 1;
} catch (IllegalArgumentException IAEx) {
newTransId = shortRecords.size() + 1;
LOGGER.warn("Failed to determine last transaction ID from CSV ("
+ lastTransactionId + "); setting to recordCount (" + newTransId + ") ..."
);
}
}
// write the new transaction record
Transaction t = new Transaction(cid, evt, accNum, rid, tsMS, newTransId, reason);
List<String> tValues = t.asList(false), fValues = t.asList(true);
shortWriter.printRecord(tValues);
shortWriter.flush();
added = true;
} catch (IOException IOEx) {
added = false;
LOGGER.error(Util.getErrorTrace(
"Failed to write transaction to \"" + transactLog.getAbsolutePath() + "\" CSV", IOEx
));
}
return added;
}
省略了事务POJO的代码,因为它与问题无关。
如何防止 CSVPrinter
在输出行之前输出 header 行? (CSV 文件已包含 header 行。)
为了不输出header行,需要在CSVPrinter
使用的CSVFormat
实例中添加.withSkipHeaderRecord(true)
,如下:
CSVFormat skipFormat = CSVFormat.DEFAULT.withQuote(null)
.withAllowMissingColumnNames(true).withTrailingDelimiter(true)
.withHeader(Transaction.getHeader(false))
.withSkipHeaderRecord(true).withIgnoreEmptyLines(true);
对 .withIgnoreEmptyLines(true)
的调用是可选的。包含它是为了不保留 empty/blank 行。
注意:如果要输出header行作为文件的第一行,创建时,可以将.withSkipHeaderRecord(true)
改为.withSkipHeaderRecord(csvFile.exists())
。这是有效的,因为文件在创建之前不存在,但在下一次写入记录时存在。