我正在尝试从GTFS读取CSV文件。在uniVocity解析器的帮助下压缩,遇到了一个我无法解决的问题。出于某种原因,某些CSV文件的第一列似乎无法正确解析。例如,在“stops.txt”文件中,如下所示:
stop_id,stop_name,stop_lat,stop_lon,location_type,parent_station
"de:3811:30215:0:6","Freiburg Stübeweg","48.0248455941735","7.85563688037231","","Parent30215"
"de:8311:30054:0:1","Freiburg Schutternstraße","48.0236251356332","7.72434519425597","","Parent30054"
"de:8311:30054:0:2","Freiburg Schutternstraße","48.0235446600679","7.72438739944883","","Parent30054"
无法正确解析“stop_id”字段,该字段的值为“null”
这是我用来读取文件的方法:
public <T> List<T> readCSV(String path, String file, BeanListProcessor<T> processor) {
List<T> content = null;
try {
// Get zip file
ZipFile zip = new ZipFile(path);
// Get CSV file
ZipEntry entry = zip.getEntry(file);
InputStream in = zip.getInputStream(entry);
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.setProcessor(processor);
parserSettings.setHeaderExtractionEnabled(true);
CsvParser parser = new CsvParser(parserSettings);
parser.parse(new InputStreamReader(in));
content = processor.getBeans();
zip.close();
return content;
} catch (Exception e) {
e.printStackTrace();
}
return content;
}
这就是我的Stop课程的样子:
public class Stop {
@Parsed
private String stop_id;
@Parsed
private String stop_name;
@Parsed
private String stop_lat;
@Parsed
private String stop_lon;
@Parsed
private String location_type;
@Parsed
private String parent_station;
public Stop() {
}
public Stop(String stop_id, String stop_name, String stop_lat, String stop_lon, String location_type,
String parent_station) {
this.stop_id = stop_id;
this.stop_name = stop_name;
this.stop_lat = stop_lat;
this.stop_lon = stop_lon;
this.location_type = location_type;
this.parent_station = parent_station;
}
// --------------------- Getter --------------------------------
public String getStop_id() {
return stop_id;
}
public String getStop_name() {
return stop_name;
}
public String getStop_lat() {
return stop_lat;
}
public String getStop_lon() {
return stop_lon;
}
public String getLocation_type() {
return location_type;
}
public String getParent_station() {
return parent_station;
}
// --------------------- Setter --------------------------------
public void setStop_id(String stop_id) {
this.stop_id = stop_id;
}
public void setStop_name(String stop_name) {
this.stop_name = stop_name;
}
public void setStop_lat(String stop_lat) {
this.stop_lat = stop_lat;
}
public void setStop_lon(String stop_lon) {
this.stop_lon = stop_lon;
}
public void setLocation_type(String location_type) {
this.location_type = location_type;
}
public void setParent_station(String parent_station) {
this.parent_station = parent_station;
}
@Override
public String toString() {
return "Stop [stop_id=" + stop_id + ", stop_name=" + stop_name + ", stop_lat=" + stop_lat + ", stop_lon="
+ stop_lon + ", location_type=" + location_type + ", parent_station=" + parent_station + "]";
}
}
如果我调用的方法,我得到这个输出是不正确的:
PartialReading pr = new PartialReading();
List<Stop> stops = pr.readCSV("VAGFR.zip", "stops.txt", new BeanListProcessor<Stop>(Stop.class));
for (int i = 0; i < 4; i++) {
System.out.println(stops.get(i).toString());
}
输出:
Stop [stop_id=null, stop_name=Freiburg Stübeweg, stop_lat=48.0248455941735, stop_lon=7.85563688037231, location_type=null, parent_station=Parent30215]
Stop [stop_id=null, stop_name=Freiburg Schutternstraße, stop_lat=48.0236251356332, stop_lon=7.72434519425597, location_type=null, parent_station=Parent30054]
Stop [stop_id=null, stop_name=Freiburg Schutternstraße, stop_lat=48.0235446600679, stop_lon=7.72438739944883, location_type=null, parent_station=Parent30054]
Stop [stop_id=null, stop_name=Freiburg Waltershofen Ochsen, stop_lat=48.0220902613143, stop_lon=7.7205756507492, location_type=null, parent_station=Parent30055]
有人知道为什么会发生这种情况,以及我如何解决它吗?在我测试的“routes.txt”和“trips.txt”文件中也会发生这种情况。这是GTFS文件:http://stadtplan.freiburg.de/sld/VAGFR.zip
如果打印标题,您会注意到第一列看起来不正确。这是因为您正在解析一个使用带有BOM标记的UTF-8编码的文件。
基本上,文件以几个字节开始,指示编码是什么。直到2.5版。*,解析器没有在内部处理这个问题,您必须跳过这些字节才能获得正确的输出:
//... your code here
ZipEntry entry = zip.getEntry(file);
InputStream in = zip.getInputStream(entry);
if(in.read() == 239 & in.read() == 187 & in.read() == 191){
System.out.println("UTF-8 with BOM, bytes discarded");
}
CsvParserSettings parserSettings = new CsvParserSettings();
//...rest of your code here
上述黑客攻击将适用于2.5之前的任何版本。*,但是你也可以使用Commons IO,它提供了一个BOMInputStream
,以方便和更干净地处理这类事情——只是速度非常慢。
更新到最新版本应该会自动处理。
希望有帮助。
是否可以根据索引范围将一行解析为多个bean 例: 行:“字段1”、“字段2”、“字段3”。。。。,“字段9”
我正在为我的一个项目评估Univocity解析器,固定宽度平面文件格式从三个细节记录(例如,以AA、BB、CC开头)生成一个记录(Bean)——这个文件可以使用Univocity解析吗 我可以使用继续阅读并添加一些自定义转换,但是是否有现成的? 更新: 可以使用:?
我试图使用univocity解析器将csv文件解析为bean的新实例和现有实例。csv是通过使用univocity BeanWriterProcessor生成的,对于我将称为set a的一组bean。 现在我想读回csv,执行以下操作: 案例1:如果行对应于最初出现在集合a中的一个bean,我不想创建一个新的bean实例,而是将csv读入“现有”实例。(即,“更新”实例)。我通过使用bean的UU
我如何在ItemReader中使用Univocity一次读取一行,仍然使用BeanProcessor将我的行自动解析为Java对象?
我有一个文件,它有固定的行,但每一行都映射到不同的Java类。 例如 对于第一排,我有后续类: 第二排我有: 我想将TSV文件直接解析到相应的对象,但我没有什么想法。
我想知道在使用CsvRoutines包时,是否有方法检查和验证字段。基本上,如果第一列只有数字,我想处理一行,否则跳过/可能抛出异常。我猜2.7.0中发布的@Validate annotation可以实现这一点。但我想知道,是否有其他方法可以在早期版本(如2.5.9)中实现同样的效果?