通过debug最后定位到了断点A和断点B之间,当代码从断点A运行到断点B时,文件中的所有中文数据都变成了乱码,但是这段代码啥也没干啊(断点B那一行代码没有执行),为什么会使文件数据发生变化呢?唯一的线索就是当代码从catch那一行执行到断点B时卡顿了一下然后文件数据就乱码了,可能这中间发生了什么吧
上图代码所在的方法commit()完整代码如下,我就是调用的这个方法完成对shp文件某条记录的修改,上图代码在下面代码的73~79行
* @see org.geotools.data.Transaction.State#commit()
*/
public synchronized void commit() throws IOException {
if (diff.isEmpty()) {
return; // nothing to do
}
ContentEntry entry = state.getEntry();
Name name = entry.getName();
ContentDataStore dataStore = entry.getDataStore();
ContentFeatureSource source = (ContentFeatureSource) dataStore.getFeatureSource(name);
SimpleFeature feature;
SimpleFeature update;
Throwable cause = null;
try (FeatureWriter<SimpleFeatureType, SimpleFeature> writer =
getWriter(name, dataStore, source)) {
while (writer.hasNext()) {
feature = writer.next();
String fid = feature.getID();
if (diff.getModified().containsKey(fid)) {
update = diff.getModified().get(fid);
if (update == Diff.NULL) {
writer.remove();
} else {
try {
feature.setAttributes(update.getAttributes());
writer.write();
} catch (IllegalAttributeException e) {
throw new DataSourceException("Could update " + fid, e);
}
}
}
}
SimpleFeature addedFeature;
SimpleFeature nextFeature;
synchronized (diff) {
for (String fid : diff.getAddedOrder()) {
addedFeature = diff.getAdded().get(fid);
nextFeature = writer.next();
if (nextFeature == null) {
throw new DataSourceException("Could not add " + fid);
} else {
try {
nextFeature.setAttributes(addedFeature.getAttributes());
// if( Boolean.TRUE.equals(
// addedFeature.getUserData().get(Hints.USE_PROVIDED_FID)) ){
nextFeature.getUserData().put(Hints.USE_PROVIDED_FID, true);
if (addedFeature.getUserData().containsKey(Hints.PROVIDED_FID)) {
String providedFid =
(String) addedFeature.getUserData().get(Hints.PROVIDED_FID);
nextFeature.getUserData().put(Hints.PROVIDED_FID, providedFid);
} else {
nextFeature
.getUserData()
.put(Hints.PROVIDED_FID, addedFeature.getID());
}
// }
writer.write();
} catch (IllegalAttributeException e) {
throw new DataSourceException("Could update " + fid, e);
}
}
}
}
} catch (IOException | RuntimeException e) {
cause = e;
throw e;
} finally {
try {
state.fireBatchFeatureEvent(true);
diff.clear();
} catch (RuntimeException e) {
if (cause != null) {
e.initCause(cause);
}
throw e;
}
}
}
乱码的数据如下,在arcgis中展示的
再贴一点代码
我构造文件存储对象datastore并设置GBK编码的方法:
public static ShapefileDataStore buildDataStore(String shpFilePath) {
ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory();
try {
ShapefileDataStore dataStore = (ShapefileDataStore) factory
.createDataStore(new File(shpFilePath).toURI().toURL());
if (dataStore != null) {
dataStore.setCharset(Charset.forName("GBK"));
}
return dataStore;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
更新文件某条数据记录的方法(在这里调用了上述commit()方法)
public static void updateShpValue(ShapefileDataStore dataStore, String fid, String propertyName, String value) throws IOException {
Transaction transaction = new DefaultTransaction("change_"+propertyName+"_"+fid);
String typeName = dataStore.getTypeNames()[0];
SimpleFeatureStore store = (SimpleFeatureStore) dataStore.getFeatureSource(typeName);
store.setTransaction(transaction);
FilterFactory ff = CommonFactoryFinder.getFilterFactory( GeoTools.getDefaultHints() );
Filter filter = ff.id(Collections.singleton(ff.featureId(fid)));
try {
store.modifyFeatures(propertyName, value, filter);
transaction.commit();
} catch(Exception eek){
transaction.rollback();
System.out.println("change_"+propertyName+"_"+fid+":转换错误");
}
}