У меня есть требование для разбора плоского файла:
column1|column2|column3$#
data1|data2|data3$#
Где
| - pipe line delimiter
$# - record delimiter
Средство чтения элементов плоского файла: я пытался использовать политику разделителя пользовательских записей, в которой я пытался переопределить isEndofRecord
и SuffixRecordSeparatorPolicy setSuffix()
, но без удачи. Он не распознает $#
в качестве разделителя записей, и я получил исключение синтаксического анализа плоского файла.
У меня есть анализатор однозначности синтаксического анализатора, чтобы добавить пользовательский разделитель записей. Однако я не уверен, как добавить настройки анализатора CSV в метод чтения плоских файлов.
private CsvParser csvParserSetting(BeanListProcessor<Employee> rowProcessor) {
CsvParserSettings settings = new CsvParserSettings();
settings.getFormat().setLineSeparator("$#");//$#
settings.getFormat().setDelimiter("|");//|
settings.setIgnoreLeadingWhitespaces(true);
settings.setNumberOfRowsToSkip(1);
settings.setProcessor(rowProcessor);
CsvParser parser = new CsvParser(settings);
return parser;
}
@Bean
@StepScope
public FlatFileItemReader<Employee> myReader() throws FileNotFoundException {BeanListProcessor<Employee> rowProcessor = new BeanListProcessor<Employee>(Employee.class);
CsvParser parser = csvParserSetting(rowProcessor);
Request request=MappingUtil.requestMap.get("myRequest");
InputStream inputStream = awsClient.getInputStreamObject(request.getFileKeyPath());
CustomRecordSeparatorPolicy customRecordSeparatorPolicy=new CustomRecordSeparatorPolicy();
//stomRecordSeparatorPolicy.isEndOfRecord(record)
FlatFileItemReader<Employee> reader = new FlatFileItemReader<>();
reader.setResource(new InputStreamResource(inputStream));
reader.setName("filreader");
reader.setLinesToSkip(1);
// customRecordSeparatorPolicy.setSuffix("$#");
// reader.setRecordSeparatorPolicy(customRecordSeparatorPolicy);
//reader.setRecordSeparatorPolicy(recordSeparatorPolicy);
reader.setLineMapper(new DefaultLineMapper<Employee>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(MyConstats.FIELDS);
setDelimiter("|");
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Employee>() {{
setTargetType(Employee.class);
}});
}});
return reader;
}
import org.springframework.batch.item.file.separator.RecordSeparatorPolicy;
publi c Класс CustomSuffixRecordSeparatorPolicy реализует RecordSeparatorPolicy {
public static final String DEFAULT_SUFFIX = "$#";
private String suffix = DEFAULT_SUFFIX;
private boolean ignoreWhitespace = false;
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public void setIgnoreWhitespace(boolean ignoreWhitespace) {
this.ignoreWhitespace = ignoreWhitespace;
}
/*@Override
public boolean isEndOfRecord(String record) {
int fieldCount = record.split("|").length;
// String recordvalue[] =record.split("\\|");
if(fieldCount == 126) {
return true;
} else {
return false;
}
}*/
public boolean isEndOfRecord(String line) {
if (line == null) {
return true;
}
String trimmed = ignoreWhitespace ? line.trim() : line;
return trimmed.endsWith(suffix);
}
public String postProcess(String record) {
if (record==null) {
return null;
}
return record.substring(0, record.lastIndexOf(suffix));
}
@Override
public String preProcess(String record) {
return record;
}
}
header1|header2|header3$#
value1|value2|value3$#value11|value22|value33
header1|header2|header3$#value1|value2|value3$#value11|value22|value33
header1|header2|header3$#
value1|value2|value3$#
value11|value22|value33$#
в итерации 1 он правильно анализирует заголовки строк, а когда он переходит во второй раз, он пытается прочитать строку value1 | value2 | value3 $ # value11 | value22 | value33 и записи не разделяются на dif guish запись за записью.
наконец-то не получается
private String applyRecordSeparatorPolicy(String line) throws IOException {
String record = line;
while (line != null && !recordSeparatorPolicy.isEndOfRecord(record)) {
line = this.reader.readLine();
if (line == null) {
if (StringUtils.hasText(record)) {
// A record was partially complete since it hasn't ended but
// the line is null
throw new FlatFileParseException("Unexpected end of file before record complete", record, lineCount);
}
else {
// Record has no text but it might still be post processed
// to something (skipping preProcess since that was already
// done)
break;
}
}
else {
lineCount++;
}
record = recordSeparatorPolicy.preProcess(record) + line;
}
return recordSeparatorPolicy.postProcess(record);
}
мой метод окончания записи, который я попробовал сейчас. похоже, что это не удастся, если header1 | hearders ... | $ # values || в той же строке это терпит неудачу. в моем случае есть 126 заголовков $ # values-126 $ # values-126 $ # et c.
private int getPipeCount(String s){
String tmp = s;
int index = -1;
int count = 0;
while ((index=tmp.indexOf("|"))!=-1) {
tmp = tmp.substring(index+1);
count++;
}
return count;
}
public boolean isEndOfRecord(String line) {
return getPipeCount(line)==126;
}