OpenCSV-找出行号



如何知道与CSVReader类读取的行相关联的文件上的实际行号?假设这个类读取的每一行都是文件上的新行,我可以计算行数。问题是CSV文件中可能有换行符。例如,有3个"逻辑"行并不意味着我们在文件中有三个"物理"行。因此,我有一个错误报告功能,几乎总是报告错误的行号。

你知道如何确定文件上的实际行号吗?谢谢

这可以通过重写CSVReader类而不更新库来完成,如下所述:

  1. 创建一个扩展CSVReader并覆盖readNext()readNextSilently()方法的自定义CsvLineNumberReader
    public class CsvLineNumberReader extends CSVReader {
    public CsvLineNumberReader(Reader reader) {
        super(reader);
    }
    @Override
    public String[] readNext() throws IOException, CsvValidationException {
        String[] nextLine = super.readNext();
        return nextLine == null ? null :
                ArrayUtils.add(nextLine, String.valueOf(this.linesRead));
    }
    @Override
    public String[] readNextSilently() throws IOException {
        String[] nextLine = super.readNextSilently();
        return nextLine == null ? null :
                ArrayUtils.add(nextLine, "LINE_NUMBER");
    }
}
  1. CsvRecord中添加一个附加属性:
        @CsvBindByName(column = "line_number")
        private Long lineNumber;
  1. 将自定义类添加到CsvToBean
    try (Reader reader = new InputStreamReader(file.getInputStream())) {
            CsvToBean<CsvRecord> beans = new CsvToBeanBuilder<CsvRecord>(new CsvLineNumberReader(reader))
                    .withType(CsvRecord.class)
                    .withThrowExceptions(false)
                    .build();
            //Parse lines to CsvRecords
            List<CsvRecord> parsedRecords = beans.parse();

生成的CsvRecords现在将具有lineNumber

如果您愿意修改源代码,可以在中添加一个计数器

private String getNextLine()

在所在的两个位置增加计数器

br.readLine();

被调用,并将计数器作为公共财产公开。

如果您不想修改源代码,对于返回的每一行CSV,您可以将自己的计数器增加1 + the sum of the newline characters in the CSV line(可能OpenCSV正在向代码返回包含换行符的列,尽管我还没有测试这种行为)。如果列A有一个换行符,列B有两个换行符的话,那么实际的文件应该是这样的:

"这是

细胞A","和

细胞

B"

生成3个换行符(或\r\n序列,具体取决于您的平台),加上OpenCSV返回的1行。计数器增加4。

如果您愿意将开源API切换到Super CSV(区分物理行和CSV行),那么您可以使用以下3种方法:

/**
 * Gets the current position in the file. 
 * The first line of the file is line number 1.
 * 
 * @since 1.0
 */
int getLineNumber();
/**
 * Returns the untokenized CSV row that was just read 
 * (which can potentially span multiple lines in the file).
 * 
 * @return the untokenized CSV row that was just read
 * @since 2.0.0
 */
String getUntokenizedRow();
/**
 * Gets the current row number (i.e. the number of CSV records - including the 
 * header - that have been read). This differs from the lineNumber, which is 
 * the number of real lines that have been read in the file. 
 * The first row is row 1 (which is typically the header row).
 * 
 * @since 2.0.0
 */
int getRowNumber();

您写道,您需要用于错误报告的行号
CsvException类有一个可以使用的getLineNumber方法。

当然,只有当出现异常时,这才有效。

相关内容

  • 没有找到相关文章

最新更新