用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文件,用到JavaDBF,简单介绍一下

最新版本: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中的字段类型表示应该是不一致的,这里做一个类型映射和转换即可。
相关文章
|
JavaScript C# Windows
C# 通过StreamWriter输出的TXT流文件,前缀带EF BB BF
C# 通过StreamWriter输出的TXT流文件,前缀带EF BB BF
332 0
C# 通过StreamWriter输出的TXT流文件,前缀带EF BB BF
|
Oracle 关系型数据库 数据库
[20180604]在内存修改数据(bbed).txt
[20180604]在内存修改数据(bbed).txt --//以前曾经做过在内存修改数据,通过oradebug poke命令修改内存信息,相关链接: --//http://blog.itpub.net/267265/viewspace-2124466/=>[20160904]在内存修改数据.txt --//今天测试看看是否通过bbed修改数据信息的情况.使用asmm,这样/dev/shm可以看到一个一个文件。
1101 0
[20171218]修改AWR snapshot 设置.txt
[20171218]Modifying AWR snapshot settings.txt SYS@book> select * from dba_hist_wr_control;       DBID SNAP_INTERVAL     RETENTION   ...
939 0
|
Oracle 关系型数据库 Linux
[20171109]简单探究文件ab_ASM_SID.dat.txt
[20171109]简单探究文件ab_ASM_SID.dat.txt --//昨天看了一篇Solving Communication problems between DB and ASM instances.
1393 0
|
SQL Oracle 关系型数据库
[20170910]imp参数buffer的简单探究2.txt
[20170910]imp参数buffer的简单探究2.txt --//exp,imp已经很少在用,如果存在8i估计还会用一下,下面因为别人遇到升级忘记家buffer参数(8i),导致导入缓慢, --//当然还有许多因素,比如存在lob字段,不过还是简单探究参数buffer.
1093 0
|
SQL Oracle 关系型数据库
[20170908]imp参数buffer的简单探究.txt
[20170908]imp参数buffer的简单探究.txt --//exp,imp已经很少在用,如果存在8i估计还会用一下,下面因为别人遇到升级忘记家buffer参数(8i),导致导入缓慢, --//当然还有许多因素,比如存在lob字段,不过还是简单探究参数buffer.
1301 0
|
Oracle 关系型数据库 数据库管理
[20170419]bbed探究数据块.txt
[20170419]bbed探究数据块.txt --//bbed 是一个瑞士军刀,也是了解oracle内部数据块结构的好工具。我自己开始使用基本是看别人的帖子,对oracle数据块的内部也不是很了解。
1052 0
|
数据库管理
[20170411]bbed删除记录的恢复.txt
[20170411]bbed删除记录的恢复.txt --//昨天上午做的测试,链接:http://blog.itpub.net/267265/viewspace-2136933/ --//我当时并没有选择恢复记录,仅仅看删除的内容.
1043 0