3

書いているプログラムとは別のプログラムで作成された CSV ファイルがあるため、ヘッダーを変更できません。ファイルのヘッダーはControllerID,Event,Number,ReaderID,Timestamp,TransactionID,. CSVPrinter同じ CSV に行を挿入するために使用している に同じヘッダーを指定しました。ただし、プリンターがレコードを追加すると、以下に示すように、新しいレコードの前にヘッダー行が追加されます。

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が行を出力する前にヘッダー行を出力しないようにするにはどうすればよいですか? (CSV ファイルには既にヘッダー行が含まれています。)

4

1 に答える 1

6

ヘッダー行を出力しないようにするには、 で使用.withSkipHeaderRecord(true)するCSVFormatインスタンスに次のように追加する必要がありCSVPrinterます。

CSVFormat skipFormat = CSVFormat.DEFAULT.withQuote(null)
  .withAllowMissingColumnNames(true).withTrailingDelimiter(true)
  .withHeader(Transaction.getHeader(false))
  .withSkipHeaderRecord(true).withIgnoreEmptyLines(true);

への呼び出し.withIgnoreEmptyLines(true)はオプションです。空行/空白行を保持しないように含まれています。

注:ファイルの最初の行としてヘッダー行を出力する場合は、作成時.withSkipHeaderRecord(true).withSkipHeaderRecord(csvFile.exists()). これは、作成直前にはファイルが存在しないため機能しますが、レコードの次の書き込み時には存在します。

于 2018-09-03T13:52:47.430 に答える