`
linwei_211
  • 浏览: 188643 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

使用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);
  }
  fields[i].setDataType(DBFField.FIELD_TYPE_C);
  fields[i].setFieldLength(200);
  String value=s[i]+i;
//  *******这一段代码避免内容中包含中文,导致中文乱码或者丢失一半字数中文 start*******************//
//  int m = value.getBytes().length;
//  String blank="";
//  if(pWord.matcher(value).find()){//如果包含中文就要补够2倍中文字数个空格,否则会导致中文乱码
//   for(int j=0;j<m;j++){
//    blank+="  ";
//   }
//  }
//  value=value;
//  *******这一段代码避免内容中包含中文,导致中文乱码或者丢失一半字数中文 end*******************//
  rowData[i]=value;
  }
   writer.setFields(fields);
   writer.addRecord(rowData);
      writer.write(new FileOutputStream("D:\\creatDBF.dbf"));
   inputStream = new FileInputStream("D:\\creatDBF.dbf");
   reader = new DBFReader(inputStream);
   reader.setCharactersetName("GBK");
 
//   for(int i = 0;i < reader.getFieldCount(); i++){
//    DBFField dbf = reader.getField(i);
//    System.out.println(dbf.getName());
//   }
   Object[] rowValue;
   while((rowValue = reader.nextRecord())!=null){
    for(int i = 0 ; i < rowValue.length ; i++){
     System.out.println(rowValue[i]);
    }
   }
 }
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics