使用Java实现对dbf文件的简单读写

原创 2004年06月09日 17:13:00

我将dbf文件的读写基本分成四个类,Writer,Reader, Field, Exception,内容如下,如果在使用该程序包时有什么问题或者好的建议,请发mail到 iiihero#hotmail.com
下载的过程详见:http://computer.mblogger.cn/ehero/posts/31204.aspx

如果您能多Re几下本文,我将更为高兴。

/**
 * <p>Title: java访问DBF文件的接口</p>
 * <p>Description: 这个类用于表示DBF文件中的写操作</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: ict</p>
 * @author : He Xiong
 * @version 1.0
 */


package com.hexiong.jdbf;

import java.io.*;
import java.util.Calendar;

// Referenced classes of package com.hexiong.jdbf:
//            JDBFException, JDBField

public class DBFWriter
{

    public DBFWriter(String s, JDBField ajdbfield[])
        throws JDBFException
    {
        stream = null;
        recCount = 0;
        fields = null;
        fileName = null;
        dbfEncoding = null;
        fileName = s;
        try
        {
            init(new FileOutputStream(s), ajdbfield);
        }
        catch(FileNotFoundException filenotfoundexception)
        {
            throw new JDBFException(filenotfoundexception);
        }
    }

    public DBFWriter(OutputStream outputstream, JDBField ajdbfield[])
        throws JDBFException
    {
        stream = null;
        recCount = 0;
        fields = null;
        fileName = null;
        dbfEncoding = null;
        init(outputstream, ajdbfield);
    }

    public DBFWriter(String s, JDBField ajdbfield[], String s1)
        throws JDBFException
    {
        stream = null;
        recCount = 0;
        fields = null;
        fileName = null;
        dbfEncoding = null;
        fileName = s;
        try
        {
            dbfEncoding = s1;
            init(new FileOutputStream(s), ajdbfield);
        }
        catch(FileNotFoundException filenotfoundexception)
        {
            throw new JDBFException(filenotfoundexception);
        }
    }

    private void init(OutputStream outputstream, JDBField ajdbfield[])
        throws JDBFException
    {
        fields = ajdbfield;
        try
        {
            stream = new BufferedOutputStream(outputstream);
            writeHeader();
            for(int i = 0; i < ajdbfield.length; i++)
                writeFieldHeader(ajdbfield[i]);

            stream.write(13);
            stream.flush();
        }
        catch(Exception exception)
        {
            throw new JDBFException(exception);
        }
    }

    private void writeHeader()
        throws IOException
    {
        byte abyte0[] = new byte[16];
        abyte0[0] = 3;
        Calendar calendar = Calendar.getInstance();
        abyte0[1] = (byte)(calendar.get(1) - 1900);
        abyte0[2] = (byte)calendar.get(2);
        abyte0[3] = (byte)calendar.get(5);
        abyte0[4] = 0;
        abyte0[5] = 0;
        abyte0[6] = 0;
        abyte0[7] = 0;
        int i = (fields.length + 1) * 32 + 1;
        abyte0[8] = (byte)(i % 256);
        abyte0[9] = (byte)(i / 256);
        int j = 1;
        for(int k = 0; k < fields.length; k++)
            j += fields[k].getLength();

        abyte0[10] = (byte)(j % 256);
        abyte0[11] = (byte)(j / 256);
        abyte0[12] = 0;
        abyte0[13] = 0;
        abyte0[14] = 0;
        abyte0[15] = 0;
        stream.write(abyte0, 0, abyte0.length);
        for(int l = 0; l < 16; l++)
            abyte0[l] = 0;

        stream.write(abyte0, 0, abyte0.length);
    }

    private void writeFieldHeader(JDBField jdbfield)
        throws IOException
    {
        byte abyte0[] = new byte[16];
        String s = jdbfield.getName();
        int i = s.length();
        if(i > 10)
            i = 10;
        for(int j = 0; j < i; j++)
            abyte0[j] = (byte)s.charAt(j);

        for(int k = i; k <= 10; k++)
            abyte0[k] = 0;

        abyte0[11] = (byte)jdbfield.getType();
        abyte0[12] = 0;
        abyte0[13] = 0;
        abyte0[14] = 0;
        abyte0[15] = 0;
        stream.write(abyte0, 0, abyte0.length);
        for(int l = 0; l < 16; l++)
            abyte0[l] = 0;

        abyte0[0] = (byte)jdbfield.getLength();
        abyte0[1] = (byte)jdbfield.getDecimalCount();
        stream.write(abyte0, 0, abyte0.length);
    }

    public void addRecord(Object aobj[])
        throws JDBFException
    {
        if(aobj.length != fields.length)
            throw new JDBFException("Error adding record: Wrong number of values. Expected " + fields.length + ", got " + aobj.length + ".");
        int i = 0;
        for(int j = 0; j < fields.length; j++)
            i += fields[j].getLength();

        byte abyte0[] = new byte[i];
        int k = 0;
        for(int l = 0; l < fields.length; l++)
        {
            String s = fields[l].format(aobj[l]);
            byte abyte1[];
            try
            {
                if(dbfEncoding != null)
                    abyte1 = s.getBytes(dbfEncoding);
                else
                    abyte1 = s.getBytes();
            }
            catch(UnsupportedEncodingException unsupportedencodingexception)
            {
                throw new JDBFException(unsupportedencodingexception);
            }
            for(int i1 = 0; i1 < fields[l].getLength(); i1++)
                abyte0[k + i1] = abyte1[i1];

            k += fields[l].getLength();
        }

        try
        {
            stream.write(32);
            stream.write(abyte0, 0, abyte0.length);
            stream.flush();
        }
        catch(IOException ioexception)
        {
            throw new JDBFException(ioexception);
        }
        recCount++;
    }

    public void close()
        throws JDBFException
    {
        try
        {
            stream.write(26);
            stream.close();
            RandomAccessFile randomaccessfile = new RandomAccessFile(fileName, "rw");
            randomaccessfile.seek(4L);
            byte abyte0[] = new byte[4];
            abyte0[0] = (byte)(recCount % 256);
            abyte0[1] = (byte)((recCount / 256) % 256);
            abyte0[2] = (byte)((recCount / 0x10000) % 256);
            abyte0[3] = (byte)((recCount / 0x1000000) % 256);
            randomaccessfile.write(abyte0, 0, abyte0.length);
            randomaccessfile.close();
        }
        catch(IOException ioexception)
        {
            throw new JDBFException(ioexception);
        }
    }

    private BufferedOutputStream stream;
    private int recCount;
    private JDBField fields[];
    private String fileName;
    private String dbfEncoding;
}

/**
 * <p>Title: java访问DBF文件的接口</p>
 * <p>Description: 这个类用于表示DBF文件中的字段</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: ict</p>
 * @author : He Xiong
 * @version 1.0
 */

package com.hexiong.jdbf;

import java.text.*;
import java.util.Date;

// Referenced classes of package com.hexiong.jdbf:
//            JDBFException

public class JDBField
{

    public JDBField(String s, char c, int i, int j)
        throws JDBFException
    {
        if(s.length() > 10)
            throw new JDBFException("The field name is more than 10 characters long: " + s);
        if(c != 'C' && c != 'N' && c != 'L' && c != 'D' && c != 'F')
            throw new JDBFException("The field type is not a valid. Got: " + c);
        if(i < 1)
            throw new JDBFException("The field length should be a positive integer. Got: " + i);
        if(c == 'C' && i >= 254)
            throw new JDBFException("The field length should be less than 254 characters for character fields. Got: " + i);
        if(c == 'N' && i >= 21)
            throw new JDBFException("The field length should be less than 21 digits for numeric fields. Got: " + i);
        if(c == 'L' && i != 1)
            throw new JDBFException("The field length should be 1 characater for logical fields. Got: " + i);
        if(c == 'D' && i != 8)
            throw new JDBFException("The field length should be 8 characaters for date fields. Got: " + i);
        if(c == 'F' && i >= 21)
            throw new JDBFException("The field length should be less than 21 digits for floating point fields. Got: " + i);
        if(j < 0)
            throw new JDBFException("The field decimal count should not be a negative integer. Got: " + j);
        if((c == 'C' || c == 'L' || c == 'D') && j != 0)
            throw new JDBFException("The field decimal count should be 0 for character, logical, and date fields. Got: " + j);
        if(j > i - 1)
        {
            throw new JDBFException("The field decimal count should be less than the length - 1. Got: " + j);
        } else
        {
            name = s;
            type = c;
            length = i;
            decimalCount = j;
            return;
        }
    }

    public String getName()
    {
        return name;
    }

    public char getType()
    {
        return type;
    }

    public int getLength()
    {
        return length;
    }

    public int getDecimalCount()
    {
        return decimalCount;
    }

    public String format(Object obj)
        throws JDBFException
    {
        if(type == 'N' || type == 'F')
        {
            if(obj == null)
                obj = new Double(0.0D);
            if(obj instanceof Number)
            {
                Number number = (Number)obj;
                StringBuffer stringbuffer = new StringBuffer(getLength());
                for(int i = 0; i < getLength(); i++)
                    stringbuffer.append("#");

                if(getDecimalCount() > 0)
                    stringbuffer.setCharAt(getLength() - getDecimalCount() - 1, '.');
                DecimalFormat decimalformat = new DecimalFormat(stringbuffer.toString());
                String s1 = decimalformat.format(number);
                int k = getLength() - s1.length();
                if(k < 0)
                    throw new JDBFException("Value " + number + " cannot fit in pattern: '" + stringbuffer + "'.");
                StringBuffer stringbuffer2 = new StringBuffer(k);
                for(int l = 0; l < k; l++)
                    stringbuffer2.append(" ");

                return stringbuffer2 + s1;
            } else
            {
                throw new JDBFException("Expected a Number, got " + obj.getClass() + ".");
            }
        }
        if(type == 'C')
        {
            if(obj == null)
                obj = "";
            if(obj instanceof String)
            {
                String s = (String)obj;
                if(s.length() > getLength())
                    throw new JDBFException("'" + obj + "' is longer than " + getLength() + " characters.");
                StringBuffer stringbuffer1 = new StringBuffer(getLength() - s.length());
                for(int j = 0; j < getLength() - s.length(); j++)
                    stringbuffer1.append(' ');

                return s + stringbuffer1;
            } else
            {
                throw new JDBFException("Expected a String, got " + obj.getClass() + ".");
            }
        }
        if(type == 'L')
        {
            if(obj == null)
                obj = new Boolean(false);
            if(obj instanceof Boolean)
            {
                Boolean boolean1 = (Boolean)obj;
                return boolean1.booleanValue() ? "Y" : "N";
            } else
            {
                throw new JDBFException("Expected a Boolean, got " + obj.getClass() + ".");
            }
        }
        if(type == 'D')
        {
            if(obj == null)
                obj = new Date();
            if(obj instanceof Date)
            {
                Date date = (Date)obj;
                SimpleDateFormat simpledateformat = new SimpleDateFormat("yyyyMMdd");
                return simpledateformat.format(date);
            } else
            {
                throw new JDBFException("Expected a Date, got " + obj.getClass() + ".");
            }
        } else
        {
            throw new JDBFException("Unrecognized JDBFField type: " + type);
        }
    }

    public Object parse(String s)
        throws JDBFException
    {
        s = s.trim();
        if(type == 'N' || type == 'F')
        {
            if(s.equals(""))
                s = "0";
            try
            {
                if(getDecimalCount() == 0)
                    return new Long(s);
                else
                    return new Double(s);
            }
            catch(NumberFormatException numberformatexception)
            {
                throw new JDBFException(numberformatexception);
            }
        }
        if(type == 'C')
            return s;
        if(type == 'L')
        {
            if(s.equals("Y") || s.equals("y") || s.equals("T") || s.equals("t"))
                return new Boolean(true);
            if(s.equals("N") || s.equals("n") || s.equals("F") || s.equals("f"))
                return new Boolean(false);
            else
                throw new JDBFException("Unrecognized value for logical field: " + s);
        }
        if(type == 'D')
        {
            SimpleDateFormat simpledateformat = new SimpleDateFormat("yyyyMMdd");
            try
            {
                if("".equals(s))
                    return null;
                else
                    return simpledateformat.parse(s);
            }
            catch(ParseException parseexception)
            {
                throw new JDBFException(parseexception);
            }
        } else
        {
            throw new JDBFException("Unrecognized JDBFField type: " + type);
        }
    }

    public String toString()
    {
        return name;
    }

    private String name;
    private char type;
    private int length;
    private int decimalCount;
}

/**
 * <p>Title: java访问DBF文件的接口</p>
 * <p>Description: 这个类用于表示DBF文件中的读写异常</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: ict</p>
 * @author : He Xiong
 * @version 1.0
 */

package com.hexiong.jdbf;

import java.io.PrintStream;
import java.io.PrintWriter;

public class JDBFException extends Exception
{

    public JDBFException(String s)
    {
        this(s, null);
    }

    public JDBFException(Throwable throwable)
    {
        this(throwable.getMessage(), throwable);
    }

    public JDBFException(String s, Throwable throwable)
    {
        super(s);
        detail = throwable;
    }

    public String getMessage()
    {
        if(detail == null)
            return super.getMessage();
        else
            return super.getMessage();
    }

    public void printStackTrace(PrintStream printstream)
    {
        if(detail == null)
        {
            super.printStackTrace(printstream);
            return;
        }
        PrintStream printstream1 = printstream;
        printstream1.println(this);
        detail.printStackTrace(printstream);
        return;
    }

    public void printStackTrace()
    {
        printStackTrace(System.err);
    }

    public void printStackTrace(PrintWriter printwriter)
    {
        if(detail == null)
        {
            super.printStackTrace(printwriter);
            return;
        }
        PrintWriter printwriter1 = printwriter;

        printwriter1.println(this);
        detail.printStackTrace(printwriter);
        return;
    }

    private Throwable detail;
}

/**
 * <p>Title: java访问DBF文件的接口</p>
 * <p>Description: 这个类用于表示DBF文件中的读操作</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: ict</p>
 * @author : He Xiong
 * @version 1.0
 */

package com.hexiong.jdbf;

import java.io.*;

// Referenced classes of package com.hexiong.jdbf:
//            JDBFException, JDBField

public class DBFReader
{

    public DBFReader(String s)
        throws JDBFException
    {
        stream = null;
        fields = null;
        nextRecord = null;
        try
        {
            init(new FileInputStream(s));
        }
        catch(FileNotFoundException filenotfoundexception)
        {
            throw new JDBFException(filenotfoundexception);
        }
    }

    public DBFReader(InputStream inputstream)
        throws JDBFException
    {
        stream = null;
        fields = null;
        nextRecord = null;
        init(inputstream);
    }

    private void init(InputStream inputstream)
        throws JDBFException
    {
        try
        {
            stream = new DataInputStream(inputstream);
            int i = readHeader();
            fields = new JDBField[i];
            int j = 1;
            for(int k = 0; k < i; k++)
            {
                fields[k] = readFieldHeader();
                j += fields[k].getLength();
            }

            if(stream.read() < 1)
                throw new JDBFException("Unexpected end of file reached.");
            nextRecord = new byte[j];
            try
            {
                stream.readFully(nextRecord);
            }
            catch(EOFException eofexception)
            {
                nextRecord = null;
                stream.close();
            }
        }
        catch(IOException ioexception)
        {
            throw new JDBFException(ioexception);
        }
    }

    private int readHeader()
        throws IOException, JDBFException
    {
        byte abyte0[] = new byte[16];
        try
        {
            stream.readFully(abyte0);
        }
        catch(EOFException eofexception)
        {
            throw new JDBFException("Unexpected end of file reached.");
        }
        int i = abyte0[8];
        if(i < 0)
            i += 256;
        i += 256 * abyte0[9];
        i = --i / 32;
        i--;
        try
        {
            stream.readFully(abyte0);
        }
        catch(EOFException eofexception1)
        {
            throw new JDBFException("Unexpected end of file reached.");
        }
        return i;
    }

    private JDBField readFieldHeader()
        throws IOException, JDBFException
    {
        byte abyte0[] = new byte[16];
        try
        {
            stream.readFully(abyte0);
        }
        catch(EOFException eofexception)
        {
            throw new JDBFException("Unexpected end of file reached.");
        }
        StringBuffer stringbuffer = new StringBuffer(10);
        for(int i = 0; i < 10; i++)
        {
            if(abyte0[i] == 0)
                break;
            stringbuffer.append((char)abyte0[i]);
        }

        char c = (char)abyte0[11];
        try
        {
            stream.readFully(abyte0);
        }
        catch(EOFException eofexception1)
        {
            throw new JDBFException("Unexpected end of file reached.");
        }
        int j = abyte0[0];
        int k = abyte0[1];
        if(j < 0)
            j += 256;
        if(k < 0)
            k += 256;
        return new JDBField(stringbuffer.toString(), c, j, k);
    }

    public int getFieldCount()
    {
        return fields.length;
    }

    public JDBField getField(int i)
    {
        return fields[i];
    }

    public boolean hasNextRecord()
    {
        return nextRecord != null;
    }

    public Object[] nextRecord()
        throws JDBFException
    {
        if(!hasNextRecord())
            throw new JDBFException("No more records available.");
        Object aobj[] = new Object[fields.length];
        int i = 1;
        for(int j = 0; j < aobj.length; j++)
        {
            int k = fields[j].getLength();
            StringBuffer stringbuffer = new StringBuffer(k);
            stringbuffer.append(new String(nextRecord, i, k));
            aobj[j] = fields[j].parse(stringbuffer.toString());
            i += fields[j].getLength();
        }

        try
        {
            stream.readFully(nextRecord);
        }
        catch(EOFException eofexception)
        {
            nextRecord = null;
        }
        catch(IOException ioexception)
        {
            throw new JDBFException(ioexception);
        }
        return aobj;
    }

    public void close()
        throws JDBFException
    {
        nextRecord = null;
        try
        {
            stream.close();
        }
        catch(IOException ioexception)
        {
            throw new JDBFException(ioexception);
        }
    }

    private DataInputStream stream;
    private JDBField fields[];
    private byte nextRecord[];
}

最后,给出一个简单的测试样例程序

/**
 * <p>Title: java访问DBF文件的接口</p>
 * <p>Description: 测试DBF文件的读写</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: ict</p>
 * @author : He Xiong
 * @version 1.0
 */

import com.hexiong.jdbf.DBFReader;
import java.io.PrintStream;
import java.net.URL;

public class Test
{

    public Test()
    {
    }

    public static void main(String args[])
        throws Exception
    {
        DBFReader dbfreader = new DBFReader("E://lakes.dbf");
        int i;
        for(i = 0; dbfreader.hasNextRecord(); i++)
        {
            Object aobj[] = dbfreader.nextRecord();
            for (int j=0; j<aobj.length; j++)
              System.out.print(aobj[j]+"  |  ");
            System.out.print("/n");
        }

        System.out.println("Total Count: " + i);
    }
}

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

最近的一个项目需要动态生成DBF文件,用到JavaDBF,简单介绍一下官方网站:http://javadbf.sarovar.org/官方英文指南:http://sarovar.org/docman/...
  • xzknet
  • xzknet
  • 2014年01月09日 17:25
  • 11023

java对DBF的Memo字段操作

最近做一个DBF数据导入,下载了javadbf-0.4.0.jar包,发现少了对memo字段读入的支持,决定对这个包的DBFReader类进行扩展,实现对memo字段的读入。memo字段的存储格式:/...
  • bee2518
  • bee2518
  • 2007年09月23日 22:57
  • 2619

使用java操作dbf文件的方法---JDBF(转载)

转自:文章来源: http://www.jdon.com/jive/thread.jsp?forum=62&thread=12421&message=7420423 ...
  • zyk_001
  • zyk_001
  • 2013年04月22日 22:16
  • 600

通过java操作dbf文件的javadbf

  • 2011年03月30日 10:27
  • 85KB
  • 下载

javadbf 读取dbf文件 支持包括memo的多种类型

下面是读取dbf中各种数据类型,包括memo类型的部分源码 public Comparable[] nextRecord(Comparable[] recordObjects)  throws D...
  • boriswu
  • boriswu
  • 2013年05月23日 17:15
  • 977

jdbc-odbc操作dbf文件

dbf分两种,一种是Dbase,另一种是Foxpro的 Dbase不用装驱动就可以操作  java 代码 如下: Connection connDbf = null;    Pre...
  • fenglacy
  • fenglacy
  • 2016年08月18日 17:42
  • 1330

Java 读取dbf文件

Java读取dbf文件,
  • changerzhuo_319
  • changerzhuo_319
  • 2016年12月01日 20:01
  • 1564

java 读写 dbf

用javabdf.jar读写bdf 读取 public static void readDBF(String path) { InputStream fis = null; try { /...
  • sjzs5590
  • sjzs5590
  • 2012年06月14日 16:05
  • 5443

java导出dbf文件大数据量的处理方法

1,用到的jar包:javadbf.jar。 2,如果是小数据量的导出,用普通的方法就可以。   用JavaDBF操作(读、写)DBF文件 最近的一个项目需要动态生成DBF文件,用到JavaD...
  • sundaywyl
  • sundaywyl
  • 2012年12月05日 14:30
  • 1242

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

http://www.iteye.com/topic/106065 用JavaDBF操作(读、写)DBF文件 最近的一个项目需要动态生成DBF文件,用到JavaDBF,简单介绍一下 官方网站...
  • Mr__fang
  • Mr__fang
  • 2012年11月02日 10:16
  • 10394
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用Java实现对dbf文件的简单读写
举报原因:
原因补充:

(最多只允许输入30个字)