您的位置:首页 > 编程语言 > Java开发

用java解析dbf文件,验证后有些dbf文件可以,解析类型为‘B’时出乱码报

2012-05-24 22:11 232 查看
java读写DBF文件 2012-02-12 15:57:18| 分类: java | 标签: |字号大



小 订阅

由于业务的需要,开发项目的时候,客户要求数据导入/导出,文件类类型为DBF文件,在网上找了一些相关源码,虽然可以完成DBF读写,但不足的是,导出文件时不支持中文字段名,字段名乱码。后经我对程序的修改,可支持中方字段名,字段名长度中5位,英文10,也可以中英文混用。下边将相关源码贴出来,供大家学习讨论,并附一读写简单例子,一共包括四个DBF读写类和一例子类。由于源码太长,不能一篇文章发完,将分成五部分。

第一部分:DBFReader.java

第二部分:DBFWriter.java

第三部分:JDBField.java

第四部分:JDBFException.java

第五部分:我写的测试例子。

不明白的可以给我留言啊。

一 DBFReader.java

import java.io.*;

// Referenced classes of package cn.edu.sut.oa.workadmin.sjcl:

// JDBFException, JDBField

public class DBFReader

{

public DBFReader(String s)

throws JDBFException

{

stream = null;

fields = null;

nextRecord = null;

nFieldCount = 0;

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();

if(fields[k] != null)

{

nFieldCount++;

j += fields[k].getLength();

}

}

nextRecord = new byte[j];

try

{

stream.readFully(nextRecord);

}

catch(EOFException eofexception)

{

nextRecord = null;

stream.close();

}

int l = 0;

for(int i1 = 0; i1 < j; i1++)

{

if(nextRecord==null)

break;

else

{

if(nextRecord[i1] != 32 && nextRecord[i1] != 42)

continue;

l = i1;

break;

}

}

if(l > 0)

{

byte abyte0[] = new byte[l];

stream.readFully(abyte0);

for(int j1 = 0; j1 < j - l; j1++)

nextRecord[j1] = nextRecord[j1 + l];

for(int k1 = 0; k1 < l; k1++)

nextRecord[j - k1 - 1] = abyte0[l - k1 - 1];

}

}

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.");

}

if(abyte0[0] == 13 || abyte0[0] == 0)

{

stream.readFully(abyte0);

return null;

}

StringBuffer stringbuffer = new StringBuffer(10);

int i = 0;

for(i = 0; i < 10; i++)

if(abyte0[i] == 0)

break;

stringbuffer.append(new String(abyte0, 0, 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 nFieldCount;

}

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[nFieldCount];

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 String[] nextRecordString()

throws JDBFException

{

if(!hasNextRecord())

throw new JDBFException("No more records available.");

String as[] = new String[nFieldCount];

int i = 1;

for(int j = 0; j < as.length; j++)

{

int k = fields[j].getLength();

StringBuffer stringbuffer = new StringBuffer(k);

stringbuffer.append(new String(nextRecord, i, k));

as[j] = stringbuffer.toString();

i += fields[j].getLength();

}

try

{

stream.readFully(nextRecord);

}

catch(EOFException eofexception)

{

nextRecord = null;

}

catch(IOException ioexception)

{

throw new JDBFException(ioexception);

}

return as;

}

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[];

private int nFieldCount;

}

java读写DBF文件(2) 2012-02-12 15:58:04| 分类: java | 标签: |字号大



小 订阅

由于业务的需要,开发项目的时候,客户要求数据导入/导出,文件类类型为DBF文件,在网上找了一些相关源码,虽然可以完成DBF读写,但不足的是,导出文件时不支持中文字段名,字段名乱码。后经我对程序的修改,可支持中方字段名,字段名长度中5位,英文10,也可以中英文混用。下边将相关源码贴出来,供大家学习讨论,并附一读写简单例子,一共包括四个DBF读写类和一例子类。由于源码太长,不能一篇文章发完,将分成五部分。

第一部分:DBFReader.java

第二部分:DBFWriter.java

第三部分:JDBField.java

第四部分:JDBFException.java

第五部分:我写的测试例子。

不明白的可以给我留言啊。

二 DBFWriter.java

import java.io.*;

import java.util.Calendar;

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];

/*定义一个新数组,用来接收新构造的字符串字节数组*/

byte abytem[];

String s = jdbfield.getName();

String news = new String();

int j = 0;

/*循环从新组成字符串,此字符串的字节长度不能大于10*/

for(int k = 0; k<s.length();k++)

{

if((s.substring(k,k+1).getBytes().length+j)>10) /*字节长度大于1的时候为汉字*/

{

break;

}

else

{

j = j + s.substring(k,k+1).getBytes().length;

news = news + s.charAt(k);

}

}

/*接收字节数组*/

abytem = news.getBytes();

/*将字数组数据合并到文件头数据组*/

for(int k = 0; k<abytem.length;k++)

{

abyte0[k] = abytem[k];

}

/*在没有地方补空*/

for(int k = j; 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;

}

java读写DBF文件(3) 2012-02-12 15:58:47| 分类: java | 标签: |字号大



小 订阅

由于业务的需要,开发项目的时候,客户要求数据导入/导出,文件类类型为DBF文件,在网上找了一些相关源码,虽然可以完成DBF读写,但不足的是,导出文件时不支持中文字段名,字段名乱码。后经我对程序的修改,可支持中方字段名,字段名长度中5位,英文10,也可以中英文混用。下边将相关源码贴出来,供大家学习讨论,并附一读写简单例子,一共包括四个DBF读写类和一例子类。由于源码太长,不能一篇文章发完,将分成五部分。

第一部分:DBFReader.java

第二部分:DBFWriter.java

第三部分:JDBField.java

第四部分:JDBFException.java

第五部分:我写的测试例子。

不明白的可以给我留言啊。

三 JDBField.java

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

// Referenced classes of package cn.edu.sut.oa.workadmin.sjcl:

// 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 == 'C' || type == 'N')

{

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 stringbuffer = new StringBuffer(getLength() - s.length());

for(int i = 0; i < getLength() - s.length(); i++)

stringbuffer.append(' ');

return s + stringbuffer;

} 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;

}

java读写DBF文件(4) 2012-02-12 15:59:31| 分类: java | 标签: |字号大



小 订阅

由于业务的需要,开发项目的时候,客户要求数据导入/导出,文件类类型为DBF文件,在网上找了一些相关源码,虽然可以完成DBF读写,但不足的是,导出文件时不支持中文字段名,字段名乱码。后经我对程序的修改,可支持中方字段名,字段名长度中5位,英文10,也可以中英文混用。下边将相关源码贴出来,供大家学习讨论,并附一读写简单例子,一共包括四个DBF读写类和一例子类。由于源码太长,不能一篇文章发完,将分成五部分。

第一部分:DBFReader.java

第二部分:DBFWriter.java

第三部分:JDBField.java

第四部分:JDBFException.java

第五部分:我写的测试例子。

不明白的可以给我留言啊。

四 JDBFException.java

import java.io.PrintStream;

import java.io.PrintWriter;

public class JDBFException extends Exception

{

private static final long serialVersionUID = 1079752281227294498L;

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;

} else

{

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;

} else

{

PrintWriter printwriter1 = printwriter;

printwriter1.println(this);

detail.printStackTrace(printwriter);

return;

}

}

private Throwable detail;

}

java读写DBF文件(5) 2012-02-12 16:00:47| 分类: java | 标签: |字号大



小 订阅

由于业务的需要,开发项目的时候,客户要求数据导入/导出,文件类类型为DBF文件,在网上找了一些相关源码,虽然可以完成DBF读写,但不足的是,导出文件时不支持中文字段名,字段名乱码。后经我对程序的修改,可支持中方字段名,字段名长度中5位,英文10,也可以中英文混用。下边将相关源码贴出来,供大家学习讨论,并附一读写简单例子,一共包括四个DBF读写类和一例子类。由于源码太长,不能一篇文章发完,将分成五部分。

第一部分:DBFReader.java

第二部分:DBFWriter.java

第三部分:JDBField.java

第四部分:JDBFException.java

第五部分:我写的测试例子。

不明白的可以给我留言啊。

/**

* DBF文件读写简单例子

*

* @author Eric 2007-6-22

* @version 1.0

*/

public class mytest {

/**

* 读DBF文件

*/

private static void readDBF()

{

try

{

System.out.println("正在读取文件!");

DBFReader dbfreader = new DBFReader("d:/aa.dbf");

for(int b = 0;b<dbfreader.getFieldCount();b++)

{

if(b>0)

System.out.print(",");

System.out.print(dbfreader.getField(b).getName().trim().toUpperCase());

if(b == (dbfreader.getFieldCount()-1))

System.out.print("\n");

}

for(int i = 0;dbfreader.hasNextRecord();i++)

{

String aobj[] = dbfreader.nextRecordString();

for(int b = 0;b<dbfreader.getFieldCount();b++)

{

if(b>0)

System.out.print(",");

System.out.print(aobj[b].trim());

if(b == (dbfreader.getFieldCount()-1))

System.out.print("\n");

}

}

System.out.println("读取文件成功!");

}

catch(Exception e)

{

e.printStackTrace();

}

}

/**

* 写DBF文件

*/

private static void writeDBF()

{

try {

JDBField ajdbfield[] = new JDBField[4];

ajdbfield[0] = new JDBField("字段1",'C',20,0);

ajdbfield[1] = new JDBField("字段2",'C',20,0);

ajdbfield[2] = new JDBField("filed3",'C',20,0);

ajdbfield[3] = new JDBField("filed4",'C',20,0);

System.out.println("正在生成DBF字段!");

DBFWriter dbfwriter = new DBFWriter("d:/aa.dbf", ajdbfield); /*生成 DBF 文件*/

Object aobj[] = new Object[4];

aobj[0]="1";

aobj[1]="1";

aobj[2]="1";

aobj[3]="1";

System.out.println("正在写入数据!");

dbfwriter.addRecord(aobj);

dbfwriter.close();

System.out.println("执行成功!");

} catch (JDBFException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public static void main(String[] args)

{

writeDBF();

readDBF();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐