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

类别:Java 点击:0 评论:0 推荐:

将dbf文件的读写基本分成四个类,Writer,Reader, Field, Exception,内容如下,如果需要其Doc文档和完整源码包,请发mail至[email protected]

/**
 * <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);
    }
}

本文地址:http://com.8s8s.com/it/it16391.htm