如何知道与CSVReader类读取的行相关联的文件上的实际行号?假设这个类读取的每一行都是文件上的新行,我可以计算行数。问题是CSV文件中可能有换行符。例如,有3个"逻辑"行并不意味着我们在文件中有三个"物理"行。因此,我有一个错误报告功能,几乎总是报告错误的行号。
你知道如何确定文件上的实际行号吗?谢谢
这可以通过重写CSVReader
类而不更新库来完成,如下所述:
- 创建一个扩展
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");
}
}
- 在
CsvRecord
中添加一个附加属性:
@CsvBindByName(column = "line_number")
private Long lineNumber;
- 将自定义类添加到
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
方法。
当然,只有当出现异常时,这才有效。