日期:2014-05-16  浏览次数:20554 次

使用JAVA写出DBF意外出现失败

????? 目前在做项目的时候,用java导出DBF的时候又遇到一个问题,因为我导出DBF的列是动态的,是查出数据库不同的表直接然后去解析去生成的DBF文件的各列,所以就出现有时候有的表导出失败,报的异常是

java.lang.IllegalArgumentException: Field name should be of length 0-10,这种异常的话还比较明确,有的时候报的是java.lang.NegativeArraySizeException,意思是数组越界了,数组索引为赋值。

后来把那些失败的数据,单独写了个测试类,便发现了一个问题,DBF文件的列名最多支持10个字符。我的解决办法是写出DBF的时候,对列名进行判断,如果包含中文而且长度超过10个字符,就只取前五个汉字。总不能让代码报错,导不出去DBF文件,被用户骂的好.....

???? 后来解决了上述问题发现列内容没有超过255,导出的DBF也出现了中文乱码的情况,比如一列内容为“你好中国”导出以后便成为“你好?”,“测试”导出以后就变为“测”,而内容是全英文的,却可以正常导出,内容中包含中文,导致导出DBF文件中文乱码或者丢失一半字数中文。也就是下面蓝色显示代码解决的此问题,如果包含中文就要补够2倍中文字数个空格,否则会导致中文乱码,可能dbf的那个jar包中没有对汉字进行处理英文他知道是一个字符,汉字他不知道是几个字符,所以就出问题了,于是只能手动的给补空格,遇到多少个汉字,补够双倍中文字数的空格,解决导出丢汉字的问题。

???? 不过我之所以又将蓝色那段代码注释掉了,是因为我这个项目不仅需要导出DBF,还需要导入DBF,发现将导出的DBF导进去的时候,读取DBF文件内容的时候,老是报jar包中空指针异常,那便是之前导出的时候补的空格导致的问题,于是修改了jar源码包,解决导出问题:内容中包含中文,导致中文乱码或者丢失一半字数中文。

我在下面也挂上修改前、后的jar包,javadbf-0[1].4.0.jar是原始的,javadbf-0[2].4.0.jar是修改后的。

如果此篇文章没有可以帮到大家的,还可以查看另外一篇文章,《使用JAVA写出DBF出现乱码和数据错位》,连接地址如下:http://linwei-211.iteye.com/blog/1207354

?

直接贴上本次测试代码吧,用代码说话。

package cn.test.test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Pattern;

import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFReader;
import com.linuxense.javadbf.DBFWriter;

public class test {
?private static FileInputStream inputStream;
?private static DBFReader reader;?????? //读取dbf文件对象

?public static void main(String args[]) throws IOException{
? String str="姓名,性别,籍贯,家庭成员,家庭详细住址";
? String s[]=str.split(",");
? DBFField[] fields = new DBFField[s.length];
? Object[] rowData = new Object[s.length];
? DBFWriter writer = new DBFWriter();
? writer.setCharactersetName("GBK");
? for(int i=0;i<s.length;i++){
??str = s[i];
??fields[i] = new DBFField();
//??********这一段代码避免列名超过10个字符,造成的异常
start***************************************************//
??/**
?? * 第一种异常信息:
?? *
java.lang.IllegalArgumentException: Field name should be of length 0-10
???*?? at com.linuxense.javadbf.DBFField.setName(DBFField.java:122)
?? * 第二种异常信息:
?? *
java.lang.NegativeArraySizeException
?? *?? at com.linuxense.javadbf.DBFField.write(DBFField.java:78)
?? *?? at com.linuxense.javadbf.DBFHeader.write(DBFHeader.java:129)
?? *?? at com.linuxense.javadbf.DBFWriter.write(DBFWriter.java:218)
?? *
?? *
?? */
??Pattern pWord = Pattern.compile("[\u4e00-\u9fa5]");//校验中文的正则表达式
??if(pWord.matcher(str).find()&&str.length()>5){//如果是中文,就只要前5个字,原因是dbf文件的列名只支持最多10个字符
???fields[i].setName(str.substring(0,5));
??}else{
//??********这一段代码避免列名超过10个字符,造成的异常 end***************************************************//
???fields[i].setName(str