博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用javaDBF操作(读、写)DBF文件
阅读量:5927 次
发布时间:2019-06-19

本文共 12872 字,大约阅读时间需要 42 分钟。

下面是分别是读取和写DBF文件以及其他操作函数。

读取DBF文件:

package dbf;import java.io.FileInputStream;import java.io.InputStream;import com.linuxense.javadbf.DBFField;import com.linuxense.javadbf.DBFReader;public class readDBF {    public static void readDBF(String path) {        InputStream fis = null;        try {            // 读取文件的输入流            fis = new FileInputStream(path);            // 根据输入流初始化一个DBFReader实例,用来读取DBF文件信息            DBFReader reader = new DBFReader(fis);            // 调用DBFReader对实例方法得到path文件中字段的个数            int fieldsCount = reader.getFieldCount();            // 取出字段信息            for (int i = 0; i < fieldsCount; i++) {                DBFField field = reader.getField(i);                System.out.println(field.getName());            }            Object[] rowValues;            // 一条条取出path文件中记录            while ((rowValues = reader.nextRecord()) != null) {                for (int i = 0; i < rowValues.length; i++) {                    System.out.println(rowValues[i]);                }            }        } catch (Exception e) {            e.printStackTrace();        } finally {            try {                fis.close();            } catch (Exception e) {            }        }    }        public static void main(String[] args) {        readDBF.readDBF("c:/到货明细表.DBF");    }}

写DBF文件:

package dbf;import java.io.FileOutputStream;import java.io.OutputStream;import com.linuxense.javadbf.DBFField;import com.linuxense.javadbf.DBFWriter;public class writeDBF {    public static void writeDBF(String path) {        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(20);            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();            // 把字段信息写入DBFWriter实例,即定义表结构            writer.setFields(fields);            // 一条条的写入记录            Object[] rowData = new Object[3];            rowData[0] = "1000";            rowData[1] = "John";            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(path);            // 写入数据            writer.write(fos);            // writer.write();        } catch (Exception e) {            e.printStackTrace();        } finally {            try {                fos.close();            } catch (Exception e) {            }        }    }}

注意: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文件,不用每次都去写重复的代码。

package dbf;import java.io.FileOutputStream;import java.io.OutputStream;import com.linuxense.javadbf.DBFField;import com.linuxense.javadbf.DBFWriter;public class Snippet {    public static void generateDbfFromArray(String dbfName, String[] strutName,            byte[] strutType, int[] strutLength, Object[][] data) {        OutputStream fos = null;        try {            int fieldCount = strutName.length;            DBFField[] fields = new DBFField[fieldCount];            for (int i = 0; i < fieldCount; i++) {                fields[i] = new DBFField();                fields[i].setName(strutName[i]);                fields[i].setDataType(strutType[i]);                fields[i].setFieldLength(strutLength[i]);            }            DBFWriter writer = new DBFWriter();            writer.setFields(fields);            for (int i = 0; i < fieldCount; i++) {                writer.addRecord(data[i]);            }            fos = new FileOutputStream(dbfName);            writer.write(fos);        } catch (Exception e) {            e.printStackTrace();        } finally {            try {                fos.close();            } catch (Exception e) {            }        }    }}

可以看到定义JavaDBF表结构或者添加数据时是通过传递数组实现,也就是说只要我们有了这些用来构造表结果和表示结果集的数组就有了DBF文件,那么我们可以通过类似下面这样的函数把ResultSet信息转换成数组信息。

public static void ResultsetToArray(ResultSet rs) {        try {            ResultSetMetaData meta = rs.getMetaData();            int columnCount = meta.getColumnCount();            String[] strutName = new String[columnCount];            byte[] strutType = new byte[columnCount];            rs.last();            int itemCount = rs.getRow();            rs.first();            Object[][] data = new Object[columnCount][itemCount];            for (int i = 0; i < columnCount; i++) {                strutType[i] = (byte) meta.getColumnType(i);                strutName[i] = meta.getColumnName(i);            }            for (int i = 0; rs.next(); i++) {                for (int j = 0; j < columnCount; j++) {                    data[i][j] = rs.getObject(j);                }            }        } catch (Exception e) {            e.printStackTrace();        }    }

细心的读者可能会发现:strutType[i] = (byte)meta.getColumnType(i)这条语句是不可靠的,的却,这里的代码我省略了,JavaDBF中的字段类型表示和ResultSetMetaData中的字段类型表示应该是不一致的,这里做一个类型映射和转换即可。

 

下面是封装好的一个读写DBF文件的工具类(仅供参考):

/** * Copyright (C) 2009 numenzq studio. All Rights Reserved. */package com.linkstec.mot.job.util;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.InvocationTargetException;import java.math.BigDecimal;import java.util.ArrayList;import java.util.List;import org.apache.commons.beanutils.PropertyUtils;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.linuxense.javadbf.DBFField;import com.linuxense.javadbf.DBFReader;import com.linuxense.javadbf.DBFWriter;/** * DBF 文件解析 * */public class DbfUtil {        private final static  String CHARSET = "GB2312";    /**     * 读DBF文件     * @param file     * @param clazz     * @param template     * @return     * @throws DocumentException     * @throws InstantiationException     * @throws IllegalAccessException     * @throws InvocationTargetException     * @throws NoSuchMethodException     * @throws IOException     */    public static 
List
readDbf(File file, Class
clazz, InputStream template) throws DocumentException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException { FileInputStream fis = new FileInputStream(file); DBFReader reader = new DBFReader(fis); reader.setCharactersetName(CHARSET); List
propertys = readTemplate(template); for(Element element : propertys){ int fieldsCount = reader.getFieldCount(); for (int i = 0; i < fieldsCount; i++) { DBFField field = reader.getField(i); if(field.getName().equals(element.attributeValue("column"))){ element.addAttribute("index", i+""); break; } } } List
records = new ArrayList
(); for (int i = 0; i < reader.getRecordCount(); i++) {// System.out.println(i+1 + "/" + reader.getRecordCount()); records.add(readLine(clazz, propertys, reader.nextRecord())); } fis.close(); return records; } /** * 写DBF文件 * @param beans * @param template * @return * @throws DocumentException * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException * @throws IOException */ public static byte[] writeDbf(List
beans, InputStream template) throws DocumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException { List
propertys = readTemplate(template); DBFWriter writer = new DBFWriter(); writer.setCharactersetName(CHARSET); writer.setFields(writeFields(propertys)); for (int i = 0; i < beans.size(); i++) { writer.addRecord(writeLine(beans.get(i), propertys)); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); writer.write(baos); return baos.toByteArray(); } /** * 写DBF文件(方式2) * @param beans * @param template * @param file * @throws DocumentException * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException * @throws IOException */ public static void writeDbf(List
beans, InputStream template,File file) throws DocumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException { List
propertys = readTemplate(template); DBFWriter writer = new DBFWriter(file); writer.setCharactersetName(CHARSET); writer.setFields(writeFields(propertys)); for (int i = 0; i < beans.size(); i++) { writer.addRecord(writeLine(beans.get(i), propertys)); } writer.write(); } /** * SAX解析表结构模板 * @param in * @return * @throws DocumentException */ @SuppressWarnings("unchecked") private static List
readTemplate(InputStream in) throws DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read(in); return (List
)document.getRootElement().elements(); } /** * 读取一行数据 * @param clazz * @param propertys * @param values * @return * @throws InstantiationException * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ private static
T readLine(Class
clazz, List
propertys, Object[] values) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { T bean = clazz.newInstance(); for (int i = 0; i < propertys.size(); i++) { Element property = propertys.get(i); if(property.attributeValue("index") != null && property.attributeValue("index").length() > 0){ int index = Integer.parseInt(property.attributeValue("index")); Object value = values[index]; if (property.attributeValue("type").equals("C")) { value = ((String) value).trim(); }else if (property.attributeValue("type").equals("N")) {// if (property.attributeValue("scale")!=null && !"".equals(property.attributeValue("scale"))) { value = new BigDecimal(((Double) value).doubleValue());// }else{// value = ((Double) value).longValue();// } }// BeanUtil.copyProperty(bean, property.attributeValue("name"), value); PropertyUtils.setProperty(bean, property.attributeValue("name"), value); } } return bean; } /** * 写一行数据 * @param bean * @param propertys * @return * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ private static Object[] writeLine(Object bean, List
propertys) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Object[] row = new Object[propertys.size()]; for (int i = 0; i < propertys.size(); i++) { Element element = propertys.get(i); row[i] = PropertyUtils.getProperty(bean, element.attributeValue("name")); } return row; } /** * 设置表结构 * @param propertys * @return */ private static DBFField[] writeFields(List
propertys) { DBFField[] fields = new DBFField[propertys.size()]; for (int i = 0; i < propertys.size(); i++) { Element property = propertys.get(i); fields[i] = new DBFField(); fields[i].setName(property.attributeValue("column")); fields[i].setDataType((byte) property.attributeValue("type").charAt(0)); if (property.attributeValue("length") != null) { fields[i].setFieldLength(Integer.parseInt(property.attributeValue("length"))); } if (property.attributeValue("scale") != null) { fields[i].setDecimalCount(Integer.parseInt(property.attributeValue("scale"))); } } return fields; } }

表结构模板实例:

 

转载于:https://www.cnblogs.com/wanglitao/p/5570275.html

你可能感兴趣的文章
程序员全国不同地区,微信(面试 招聘)群。
查看>>
【干货】界面控件DevExtreme视频教程大汇总!
查看>>
闭包 !if(){}.call()
查看>>
python MySQLdb安装和使用
查看>>
Java小细节
查看>>
poj - 1860 Currency Exchange
查看>>
chgrp命令
查看>>
Java集合框架GS Collections具体解释
查看>>
洛谷 P2486 BZOJ 2243 [SDOI2011]染色
查看>>
linux 笔记本的温度提示
查看>>
数值积分中的辛普森方法及其误差估计
查看>>
Web service (一) 原理和项目开发实战
查看>>
跑带宽度多少合适_跑步机选购跑带要多宽,你的身体早就告诉你了
查看>>
广平县北方计算机第一届PS设计大赛
查看>>
深入理解Java的接口和抽象类
查看>>
java与xml
查看>>
Javascript异步数据的同步处理方法
查看>>
快速排序——Java
查看>>
unity游戏与我
查看>>
187. Repeated DNA Sequences
查看>>