使用JAVAdbf对DBF文件读取与写入操作。
1.引入依赖,加载javadbf-0.4.0.jar
在pom.xml文件加入依赖
<!-- 读写dbf文件--><dependency><groupId>com.linuxense</groupId><artifactId>javadbf</artifactId><version>0.4.0</version></dependency>
自动下载javadbf-0.4.0.jar的文件有个BUG,向DBF文件写入中文的时候会出现乱码,建议下载这个文件将其maven目录下文件替换掉。资源下载地址:Javadbf时解决DBF中文写入乱码问题javadbf-0.4.0.jar_dbf-Java文档类资源-CSDN下载
2.读取DBF数据
import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFReader;
import com.linuxense.javadbf.DBFWriter;/*** 读取抄表DBF文件* @param fpath 文件全路径名*/public void importDBF(String fpath){String estr = "读取抄表DBF===:";try {//--------------读取DBF-------------//BufferedInputStream bis=null;try {File file = new File(fpath);if(!file.exists()){logger.error("文件不存在.");return ;}bis = new BufferedInputStream(new FileInputStream(file));String vcontent;DBFReader reader=new DBFReader(bis);//设置编码格式,有时候解析出来的数据有乱码的,就可以加上这句//dr.setCharactersetName("gb2312");Object[] ary;int rc= reader.getRecordCount();//逐行读取数据for (int i = 0; i < rc; i++) {ary=reader.nextRecord();if(ary==null) break;//读取第一个字段的值vcontent=new String(ary[1].toString().trim().getBytes(),"utf-8");logger.debug("字段内容:"+vcontent);};}finally {try {if (bis!=null){bis.close();}}catch (Exception e) {logger.error(estr+"关闭文件失败."+ e.toString());}}} catch (Exception e) {logger.error(estr + e.toString());}return ;}
注意:
读取DBF文件时,如果数值字段值为空,有可能出现异常报错,如“java dbf nextRecord Failed to parse Number: empty String”,或“Failed to parse Number: For input string: “-.—””等。
这些都是因为读取该行的某字段时遇null值,而该字段类型是数值类型,读取时会自动将null当成字符串转换成数值报错。
解决的办法是,将所有数值字段初始数值改为0,而字符串字段最好也设置为空字符串,不设置null值。
3.向DBF文件写入数据
//生成DBF文件private void writeDBF(){String estr = "生成DBF文件===:";try {//新文件路径String dstfile= "D:/A.DBF";//向新DBF文件写入数据FileOutputStream fos=null;try {//定义DBF文件字段DBFField[] fields = new DBFField[2];addDBFfieldStr(fields,0,"HM",20);//创建字符串字段addDBFfieldDecimal(fields,5,"HH",2);//创建数值字段//定义DBFWriter实例用来写DBF文件DBFWriter writer = new DBFWriter();//把字段信息写入DBFWriter实例,即定义表结构writer.setFields(fields);//写入记录Object[] rowData = new Object[2];rowData[0] = "户名1";rowData[1] = 22.00;//金额writer.addRecord(rowData);Object[] rowData2 = new Object[2];rowData[0] = "户名2";rowData[1] = 98.00;//金额writer.addRecord(rowData2);//定义输出流,并关联的一个文件fos = new FileOutputStream(dstfile);//写入数据writer.setCharactersetName("GBK");//设置GBK编码避免中文乱码writer.write(fos);}finally {try {if (fos != null) {fos.close();}} catch (Exception e) {rMsg.setResultMsg(e.getCause().getMessage());logger.error(estr + "关闭文件失败." + e.toString());}}} catch (Exception e) {logger.error(estr + rMsg.getResultMsg());}return ;}//创建DBF字符串字段private void addDBFfieldStr(DBFField[] fields,int index,String fieldName,int fieldLength){
// DBFField.FIELD_TYPE_C: // 字符串
// DBFField.FIELD_TYPE_M: // 可以用字符串传值
// DBFField.FIELD_TYPE_D: // 时期
// DBFField.FIELD_TYPE_F: // 数值 用Double
// DBFField.FIELD_TYPE_N: // 数值 用Double
// DBFField.FIELD_TYPE_L: // Booleanfields[index] = new DBFField();fields[index].setName(fieldName);fields[index].setDataType(DBFField.FIELD_TYPE_C);fields[index].setFieldLength(fieldLength);}//创建DBF数值字段private void addDBFfieldDecimal(DBFField[] fields,int index,String fieldName,int decimalCount){fields[index] = new DBFField();fields[index].setName(fieldName);fields[index].setDataType(DBFField.FIELD_TYPE_N);fields[index].setFieldLength(18);fields[index].setDecimalCount(decimalCount);}
Javadbf写入DBF文件,有两种方式:
1.创建新文件,然后在该文件内创建字段,然后逐行追加记录写入数据。
2.在原文件上进行追加记录,方法是 在文中DBFWriter writer = new DBFWriter();这个地方使用 DBFWriter writer = new DBFWriter(new File(dstfile)); dstfile是文件路径,不需要再定义表字段类型,可以直接对字段数组赋值并追加记录,最后使用writer.write();提交即可。
//生成DBF文件private void writeDBF(){String estr = "生成DBF文件===:";try {//新文件路径String dstfile= "D:/A.DBF";//定义DBF文件字段DBFField[] fields = new DBFField[2];//定义DBFWriter实例用来写DBF文件DBFWriter writer = new DBFWriter(new File(dstfile));//写入记录Object[] rowData = new Object[2];rowData[0] = "户名1";rowData[1] = 22.00;//金额writer.addRecord(rowData);Object[] rowData2 = new Object[2];rowData[0] = "户名2";rowData[1] = 98.00;//金额writer.addRecord(rowData2);//写入数据writer.setCharactersetName("GBK");//设置GBK编码避免中文乱码writer.write();} catch (Exception e) {logger.error(estr + rMsg.getResultMsg());}return ;}
写入中文的时候,需要特别注意设置writer的编码类型,这里设置为GBK写入的中文才会显示正常。
添加字段时,需要设置DBFField的数据类型,类型对应的枚举值,已经列在方法addDBFfieldStr的注释里面了,可以对应参考下。
异常处理
如果出现“Invalid value for field ”这样的异常报错,解决办法是在赋值数值类型的时候需要数值转换成Doulble类型,如
rowData[6] = 0;//错误
rowData[6] = Double.valueOf(0);//正确