用JavaDBF操作(读、写)DBF文件

http://www.iteye.com/topic/106065

用JavaDBF操作(读、写)DBF文件

最近的一个项目需要动态生成DBF文件,用到JavaDBF,简单介绍一下

官方网站:http://javadbf.sarovar.org/

官方英文指南:http://sarovar.org/docman/view.php/32/23/javadbf-tutorial.html

最新版本:0.4.0,最后发布时间还是在2004年4月1日,看来DBF真是老了。老归老,有些时候还是得用。

下面是分别是读取和写DBF文件以及其他操作函数(关键信息的解释我放在了注释里,这样看起来会更方便):

读取DBF文件:

[java]  view plain copy
  1. package dbf;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.io.InputStream;  
  5.   
  6. import com.linuxense.javadbf.DBFField;  
  7. import com.linuxense.javadbf.DBFReader;  
  8.   
  9. public class readDBF {  
  10.     public static void readDBF(String path) {  
  11.         InputStream fis = null;  
  12.         try {  
  13.             // 读取文件的输入流  
  14.             fis = new FileInputStream(path);  
  15.             // 根据输入流初始化一个DBFReader实例,用来读取DBF文件信息  
  16.             DBFReader reader = new DBFReader(fis);  
  17.             // 调用DBFReader对实例方法得到path文件中字段的个数  
  18.             int fieldsCount = reader.getFieldCount();  
  19.             // 取出字段信息  
  20.             for (int i = 0; i < fieldsCount; i++) {  
  21.                 DBFField field = reader.getField(i);  
  22.                 System.out.println(field.getName());  
  23.             }  
  24.             Object[] rowValues;  
  25.             // 一条条取出path文件中记录  
  26.             while ((rowValues = reader.nextRecord()) != null) {  
  27.                 for (int i = 0; i < rowValues.length; i++) {  
  28.                     System.out.println(rowValues[i]);  
  29.                 }  
  30.             }  
  31.         } catch (Exception e) {  
  32.             e.printStackTrace();  
  33.         } finally {  
  34.             try {  
  35.                 fis.close();  
  36.             } catch (Exception e) {  
  37.             }  
  38.         }  
  39.     }  
  40.       
  41.     public static void main(String[] args) {  
  42.         readDBF.readDBF("c:/到货明细表.DBF");  
  43.     }  
  44. }  

写DBF文件:

[java]  view plain copy
  1. package dbf;  
  2.   
  3. import java.io.FileOutputStream;  
  4. import java.io.OutputStream;  
  5.   
  6. import com.linuxense.javadbf.DBFField;  
  7. import com.linuxense.javadbf.DBFWriter;  
  8.   
  9. public class writeDBF {  
  10.     public static void writeDBF(String path) {  
  11.         OutputStream fos = null;  
  12.         try {  
  13.             // 定义DBF文件字段  
  14.             DBFField[] fields = new DBFField[3];  
  15.             // 分别定义各个字段信息,setFieldName和setName作用相同,  
  16.             // 只是setFieldName已经不建议使用  
  17.             fields[0] = new DBFField();  
  18.             // fields[0].setFieldName("emp_code");  
  19.             fields[0].setName("semp_code");  
  20.             fields[0].setDataType(DBFField.FIELD_TYPE_C);  
  21.             fields[0].setFieldLength(10);  
  22.             fields[1] = new DBFField();  
  23.             // fields[1].setFieldName("emp_name");  
  24.             fields[1].setName("emp_name");  
  25.             fields[1].setDataType(DBFField.FIELD_TYPE_C);  
  26.             fields[1].setFieldLength(20);  
  27.             fields[2] = new DBFField();  
  28.             // fields[2].setFieldName("salary");  
  29.             fields[2].setName("salary");  
  30.             fields[2].setDataType(DBFField.FIELD_TYPE_N);  
  31.             fields[2].setFieldLength(12);  
  32.             fields[2].setDecimalCount(2);  
  33.             // DBFWriter writer = new DBFWriter(new File(path));  
  34.             // 定义DBFWriter实例用来写DBF文件  
  35.             DBFWriter writer = new DBFWriter();  
  36.             // 把字段信息写入DBFWriter实例,即定义表结构  
  37.             writer.setFields(fields);  
  38.             // 一条条的写入记录  
  39.             Object[] rowData = new Object[3];  
  40.             rowData[0] = "1000";  
  41.             rowData[1] = "John";  
  42.             rowData[2] = new Double(5000.00);  
  43.             writer.addRecord(rowData);  
  44.             rowData = new Object[3];  
  45.             rowData[0] = "1001";  
  46.             rowData[1] = "Lalit";  
  47.             rowData[2] = new Double(3400.00);  
  48.             writer.addRecord(rowData);  
  49.             rowData = new Object[3];  
  50.             rowData[0] = "1002";  
  51.             rowData[1] = "Rohit";  
  52.             rowData[2] = new Double(7350.00);  
  53.             writer.addRecord(rowData);  
  54.             // 定义输出流,并关联的一个文件  
  55.             fos = new FileOutputStream(path);  
  56.             // 写入数据  
  57.             writer.write(fos);  
  58.             // writer.write();  
  59.         } catch (Exception e) {  
  60.             e.printStackTrace();  
  61.         } finally {  
  62.             try {  
  63.                 fos.close();  
  64.             } catch (Exception e) {  
  65.             }  
  66.         }  
  67.     }  
  68. }  

注意:writer.addRecord(rowData)时并不真正写入数据,在最后writer.write(fos)时才会把数据写入DBF文件,之前addRecord的数据暂时存放在内存中。如果数据量过大,这种方式显然不适合,内存中存储的数据过多,所以JavaDBF提供了另外一种机制来解决这个问题:Sync Mode(同步模式)。使用方法如下:

用new DBFWriter(new File(path))实例化DBFWriter类,最后写入数据时用writer.write(),这样在每次addRecord时数据就被写入的DBF文件中。

因为初始化DBFWriter时传递了DBF文件,所以不用再定义DBF表结构,如果你定义并加载表结构会报异常。

下面这个函数会根据你传入的数据信息自动生成DBF文件,这样以后我们只要构造好数组,就可以直接得到DBF文件,不用每次都去写重复的代码。

[java]  view plain copy
  1. package dbf;  
  2.   
  3. import java.io.FileOutputStream;  
  4. import java.io.OutputStream;  
  5.   
  6. import com.linuxense.javadbf.DBFField;  
  7. import com.linuxense.javadbf.DBFWriter;  
  8.   
  9. public class Snippet {  
  10.     public static void generateDbfFromArray(String dbfName, String[] strutName,  
  11.             byte[] strutType, int[] strutLength, Object[][] data) {  
  12.         OutputStream fos = null;  
  13.         try {  
  14.             int fieldCount = strutName.length;  
  15.             DBFField[] fields = new DBFField[fieldCount];  
  16.             for (int i = 0; i < fieldCount; i++) {  
  17.                 fields[i] = new DBFField();  
  18.                 fields[i].setName(strutName[i]);  
  19.                 fields[i].setDataType(strutType[i]);  
  20.                 fields[i].setFieldLength(strutLength[i]);  
  21.             }  
  22.             DBFWriter writer = new DBFWriter();  
  23.             writer.setFields(fields);  
  24.             for (int i = 0; i < fieldCount; i++) {  
  25.                 writer.addRecord(data[i]);  
  26.             }  
  27.             fos = new FileOutputStream(dbfName);  
  28.             writer.write(fos);  
  29.         } catch (Exception e) {  
  30.             e.printStackTrace();  
  31.         } finally {  
  32.             try {  
  33.                 fos.close();  
  34.             } catch (Exception e) {  
  35.             }  
  36.         }  
  37.   
  38.     }  
  39. }  
可以看到定义JavaDBF表结构或者添加数据时是通过传递数组实现,也就是说只要我们有了这些用来构造表结果和表示结果集的数组就有了DBF文件,那么我们可以通过类似下面这样的函数把ResultSet信息转换成数组信息。

[java]  view plain copy
  1. public static void ResultsetToArray(ResultSet rs) {  
  2.         try {  
  3.             ResultSetMetaData meta = rs.getMetaData();  
  4.             int columnCount = meta.getColumnCount();  
  5.             String[] strutName = new String[columnCount];  
  6.             byte[] strutType = new byte[columnCount];  
  7.             rs.last();  
  8.             int itemCount = rs.getRow();  
  9.             rs.first();  
  10.             Object[][] data = new Object[columnCount][itemCount];  
  11.             for (int i = 0; i < columnCount; i++) {  
  12.                 strutType[i] = (byte) meta.getColumnType(i);  
  13.                 strutName[i] = meta.getColumnName(i);  
  14.             }  
  15.             for (int i = 0; rs.next(); i++) {  
  16.                 for (int j = 0; j < columnCount; j++) {  
  17.                     data[i][j] = rs.getObject(j);  
  18.                 }  
  19.             }  
  20.         } catch (Exception e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.     }  

细心的读者可能会发现:strutType[i] = (byte)meta.getColumnType(i)这条语句是不可靠的,的却,这里的代码我省略了,JavaDBF中的字段类型表示和ResultSetMetaData中的字段类型表示应该是不一致的,这里做一个类型映射和转换即可。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
javadbf-0.4.0版本本已增加setCharactersetName方法支持,但在入时会发生文数据丢失问题。资源压缩文件包含有修改后的jar文件测试类。 @Test public void testWrite1(){ File file=new File(this.folder, "测试数据.DBF"); OutputStream fos = null; try { // 定义DBF文件字段 DBFField[] fields = new DBFField[3]; // 分别定义各个字段信息,setFieldName和setName作用相同, // 只是setFieldName已经不建议使用 fields[0] = new DBFField(); // fields[0].setFieldName("emp_code"); fields[0].setName("semp_code"); fields[0].setDataType(DBFField.FIELD_TYPE_C); fields[0].setFieldLength(10); fields[1] = new DBFField(); // fields[1].setFieldName("emp_name"); fields[1].setName("emp_name"); fields[1].setDataType(DBFField.FIELD_TYPE_C); fields[1].setFieldLength(200); fields[2] = new DBFField(); // fields[2].setFieldName("salary"); fields[2].setName("salary"); fields[2].setDataType(DBFField.FIELD_TYPE_N); fields[2].setFieldLength(12); fields[2].setDecimalCount(2); // DBFWriter writer = new DBFWriter(new File(path)); // 定义DBFWriter实例用来DBF文件 DBFWriter writer = new DBFWriter(); writer.setCharactersetName("GBK"); // 把字段信息DBFWriter实例,即定义表结构 writer.setFields(fields); // 一条条的入记录 Object[] rowData = new Object[3]; rowData[0] = "1000234567"; // "文";// -42 -48 -50 -60 rowData[1] = "文"; rowData[2] = new Double(5000.00); writer.addRecord(rowData); rowData = new Object[3]; rowData[0] = "1001"; rowData[1] = "Lalit"; rowData[2] = new Double(3400.00); writer.addRecord(rowData); rowData = new Object[3]; rowData[0] = "1002"; rowData[1] = "Rohit"; rowData[2] = new Double(7350.00); writer.addRecord(rowData); // 定义输出流,并关联的一个文件 fos = new FileOutputStream(file); // 入数据 /* * 注意:writer.addRecord(rowData)时并不真正入数据,在最后writer.write(fos)时才会把数据DBF文件,之前addRecord的数据暂时存放在内存。如果数据量过大,这种方式显然不适合. */ writer.write(fos); } catch (Exception e) { e.printStackTrace(); } finally { try { fos.close(); } catch (Exception e) { } } } /** * JavaDBF提供的另外一种机制:Sync Mode(同步模式)解决数据量过大这个问题 */ @Test public void testWrite2(){ File file=new File(this.folder, "测试数据.DBF"); DBFWriter writer = null; try { if(file.exists()){ file.delete(); } // 定义DBF文件字段 DBFField[] fields = new DBFField[3]; // 分别定义各个字段信息,setFieldName和setName作用相同, // 只是setFieldName已经不建议使用 fields[0] = new DBFField(); // fields[0].setFieldName("emp_code"); fields[0].setName("semp_code"); fields[0].setDataType(DBFField.FIELD_TYPE_C); fields[0].setFieldLength(10); fields[1] = new DBFField(); // fields[1].setFieldName("emp_name"); fields[1].setName("emp_name"); fields[1].setDataType(DBFField.FIELD_TYPE_C); fields[1].setFieldLength(200); fields[2] = new DBFField(); // fields[2].setFieldName("salary"); fields[2].setName("salary"); fields[2].setDataType(DBFField.FIELD_TYPE_N); fields[2].setFieldLength(12); fields[2].setDecimalCount(2); // DBFWriter writer = new DBFWriter(new File(path)); // 定义DBFWriter实例用来DBF文件 writer = new DBFWriter(file); writer.setCharactersetName("GBK"); // 把字段信息DBFWriter实例,即定义表结构 writer.setFields(fields); // 一条条的入记录 Object[] rowData = new Object[3]; rowData[0] = "1000234567"; rowData[1] = "文1"; rowData[2] = new Double(5000.00); writer.addRecord(rowData); rowData = new Object[3]; rowData[0] = "1001"; rowData[1] = "Lalit"; rowData[2] = new Double(3400.00); writer.addRecord(rowData); rowData = new Object[3]; rowData[0] = "1002"; rowData[1] = "Rohit"; rowData[2] = new Double(7350.00); writer.addRecord(rowData); } catch (Exception e) { e.printStackTrace(); } finally { if(writer!=null){ try { writer.write(); } catch (Exception e) {} } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值