Я использую Univocity parser версии 2.7.3.У меня есть CSV-файл, который содержит 1 миллион записей и может увеличиться в будущем.Я читаю только несколько конкретных столбцов из файла, и ниже приведены мои требования:
НЕ сохраняйте содержимое CSV в памяти в любой точке
Игнорировать / пропустить создание bean-компонента, если столбцы широты или долготы в CSV равны null / blank
Чтобы удовлетворить эти требования, я попытался реализовать CsvRoutines, чтобы данные CSV не копировалисьв память.Я использую аннотацию @Validate в полях «Широта» и «Долгота» и использую обработчик ошибок, чтобы не отбрасывать никаких исключений, чтобы запись пропускалась при ошибке проверки.
Пример CSV:
#version:1.0
#timestamp:2017-05-29T23:22:22.320Z
#brand:test report
network_name,location_name,location_category,location_address,location_zipcode,location_phone_number,location_latitude,location_longitude,location_city,location_state_name,location_state_abbreviation,location_country,location_country_code,pricing_type,wep_key
"1 Free WiFi","Test Restaurant","Cafe / Restaurant","Marktplatz 18","1233","+41 263 34 05","1212.15","7.51","Basel","test","BE","India","DE","premium",""
"2 Free WiFi","Test Restaurant","Cafe / Restaurant","Zufikerstrasse 1","1111","+41 631 60 00","11.354","8.12","Bremgarten","test","AG","China","CH","premium",""
"3 Free WiFi","Test Restaurant","Cafe / Restaurant","Chemin de la Fontaine 10","1260","+41 22 361 69","12.34","11.23","Nyon","Vaud","VD","Switzerland","CH","premium",""
"!.oist*~","HoistGroup Office","Office","Chemin de I Etang","CH-1211","","","","test","test","GE","Switzerland","CH","premium",""
"test","tess's Takashiro","Cafe / Restaurant","Test 1-10","870-01","097-55-1808","","","Oita","Oita","OITA","Japan","JP","premium","1234B"
TestDTO.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class TestDTO implements Serializable {
@Parsed(field = "location_name")
private String name;
@Parsed(field = "location_address")
private String addressLine1;
@Parsed(field = "location_city")
private String city;
@Parsed(field = "location_state_abbreviation")
private String state;
@Parsed(field = "location_country_code")
private String country;
@Parsed(field = "location_zipcode")
private String postalCode;
@Parsed(field = "location_latitude")
@Validate
private Double latitude;
@Parsed(field = "location_longitude")
@Validate
private Double longitude;
@Parsed(field = "network_name")
private String ssid;
}
Main.java
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.detectFormatAutomatically();
parserSettings.setLineSeparatorDetectionEnabled(true);
parserSettings.setHeaderExtractionEnabled(true);
parserSettings.setSkipEmptyLines(true);
parserSettings.selectFields("network_name", "location_name","location_address", "location_zipcode",
"location_latitude", "location_longitude", "location_city","location_state_abbreviation", "location_country_code");
parserSettings.setProcessorErrorHandler(new RowProcessorErrorHandler() {
@Override
public void handleError(DataProcessingException error, Object[] inputRow, ParsingContext context) {
//do nothing
}
});
CsvRoutines parser = new CsvRoutines(parserSettings);
ResultIterator<TestDTO, ParsingContext> iterator = parser.iterate(TestDTO.class, new FileReader("c:\\users\\...\\test.csv")).iterator();
int i=0;
while(iterator.hasNext()) {
TestDTO dto = iterator.next();
if(dto.getLongitude() == null || dto.getLatitude() == null)
i++;
}
System.out.println("count=="+i);
Проблема:
Я действительно ожидал, что счет будет равен нулю, так как я добавил обработчик ошибок и не выбросил исключение проверки данных, но, похоже, это не так.Я думал, что @Validate выдаст исключение, когда встретит запись с широтой или долготой, равной нулю (оба столбца могут быть также нулевыми в одной и той же записи), которая обрабатывается и игнорируется / пропускается в обработчике ошибок.
По сути, я не хочу, чтобы UniVocity создавала и отображала ненужные объекты DTO в куче (и приводила к нехватке памяти), поскольку есть вероятность, что входящий CSV-файл может иметь более 200 или 300 тыс. Записей с широтой / долготой, равными нулю.
Я даже пытался добавить пользовательский валидатор в @Validate, но безуспешно.
Может кто-нибудь сообщить мне, что мне здесь не хватает?