java shapefile 中文乱码_geotools修改shapefile 属性名乱码问题 (转载)

在GeoServer中文社区的讨论地址为:http://opengeo.cn/bbs/read.php?tid=1701&page=ea

使用geotools修改shapefile之后, 发现dbf文件内容中, 属性名都成了乱码, 但属性值就不是乱码。修改之前还没有乱码的。

而且在代码中也已经通过以下方式设置过编码方式了:

ShapefileDataStore shape = new ShapefileDataStore(url);

shape.setStringCharset(Charset.forName("GBK"));

我的修改代码如下:

/*** 修改shapefile.

*@paramdataStore

*@paramfidStr 要修改的数据对应的featureID

*@return*/

public static boolean updateShapeFile(ShapefileDataStore dataStore,String fidStr)

{

DefaultTransaction transaction = null;

SimpleFeatureStore store = null;

try {

dataStore.setStringCharset(Charset.forName("GBK"));

String[] featureNames = dataStore.getTypeNames();

String featureName = featureNames[0];

//创建默认的事务对象 transaction = new DefaultTransaction();

//同时标明数据源使用的要素名称,通常Shapefile文件名称和Shapefile类型名称通常是一样的。 store = (SimpleFeatureStore) dataStore.getFeatureSource(featureName);

//关联默认事务和数据源 store.setTransaction(transaction);

//创建过滤器 FilterFactory2 ff = (FilterFactory2) CommonFactoryFinder.getFilterFactory2(null);

Set fids = new HashSet();

FeatureId fid = ff.featureId(fidStr);

fids.add(fid);

Filter filter = (Filter) ff.id(fids);

//根据过滤器对过滤的feature进行修改 store.modifyFeatures("资料表编号", "test", filter);

//提交 transaction.commit();

} catch (IOException e) {

e.printStackTrace();

try {

//回滚 transaction.rollback();

} catch (IOException e1) {

e1.printStackTrace();

}

return false;

}finally{

if(transaction!=null){

//关闭 transaction.close();

transaction = null;

}

}

return true;

}

经过定位发现问题出在transaction.commit();

而且shp文件的文件内容中也有汉字,但是没有出现乱码的问题,那么就从dbf文件的文件头着手。

查看geotools的源代码,发现对dbf文件的操作都在org\geotools\data\shapefile\dbf这个包下,其中类DbaseFileWriter实现的是对dbf文件的写操作,包括属性名(head)的写入和属性值(body)的写入,而head的写入在

public DbaseFileWriter(DbaseFileHeader header, WritableByteChannel out, Charset charset)

throws IOException {

//写header

header.writeHeader(out);

。。。。。。

}

而writeHeader方法的定义在DbaseFileHeader这个类中.

原来的代码如下:

//write the field name for (int j = 0; j < 11; j++) {

if (fields.fieldName.length() > j) {

buffer.put((byte) fields.fieldName.charAt(j));

} else {

buffer.put((byte) 0);

}

}

意思就是,将属性名称以byte形式放到buffer中,一个属性名所占字节数不能超过11个,不足11个的用(byte)0补充。

关键就在(byte) fields.fieldName.charAt(j),对于汉字来说,占用两个字节,而这里从char转化成byte的时候除了问题.

就拿下面这个字符串来说:

String str = "资";

byte[] bytes = str.getBytes();

for(int i=0;i

System.out.println(bytes);

输出结果应该是:

-41

-54

这里占用两个字节,是对的.

如果按照它里面的方法的话:

char chars = '资';

byte[] bytes = {(byte)chars};

for(int i=0;i

System.out.println(bytes);

输出结果是:

68

这里明显是不对的.

就按照上面的逻辑,修改原代码如下(我这里只是方法,这段代码应该再优化一下):

int j = 0;

for(int counter=0; j<11&&counter

char cha =  fields.fieldName.charAt(counter);

String str = new String(cha+"");

byte[] bytes = str.getBytes(); //此处应改为byte[] bytes = str.getBytes(“GBK”);否则中文还是无法识别

for(int k=0;k

buffer.put(bytes[k]);

j++;

}

}

if(j!=11){

for(int k=0;k

buffer.put((byte) 0);

}

}

转载自:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值