当前位置: 首页 > 工具软件 > jdbf > 使用案例 >

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

籍昱
2023-12-01

转自:文章来源: http://www.jdon.com/jive/thread.jsp?forum=62&thread=12421&message=7420423


完全free的JDBF: http://www.svcon.com/ 这个网站主要是做数据库连接中间介的,其中用到了一个他们自己开发的叫做JDBF的项目,该项目就是专门控制dbf文件的,整个包只有30K大小,你们随便用个工具反编译一下就可以看懂里面的代码,很简单,就是按照具体格式处理文件!(注意,不是使用JDBC连接的。)

JDBF不能读取中文问题的解决方法:
JDBF对于数据的读取采用了UNICODE字符集,所以读取数据的时候不存在问题。关键在于对字段的读取不兼容中文。
打开JDBF的源码就知道,它是把.dbf作为文件流的形式读进来的,但是我不明白它为什么读取字段和读取数据要分两种方式。读取字段的时候它是这样的:从文件流中一个一个byte(字节)地读取信息,却画蛇添足地把每个字节强行转化为字符(char)型,然后再把这一传char拼接成一个String字段。 
这样就有问题了,在JAVA中一个char的大小是一个byte的两倍,这样的话,就相当于每个char的高位填入了一个为0000的空byte,对于使用高位的中文字符集来说,它就相当于每次读取了半个中文字符,然后就把这半个字符用补零的方法转换成整个中文字符,这就是JDBF不能读取中文字段名的原因。(所幸的是它在读取数据的时候却没有采用逐个byte读取的方式,所以不会出现问题。)
还有一点幸运的是,它读进来的字段虽然是错的,但是字段里面所含的信息没有丢失,我们只要把它人为填加的0000空byte去掉就可以转回真正的中文。
知道了原因,就很好解决了,下面是别人写的一个转换函数,你在通过String columnName=DBFReader.getField(i).getName()得到每一个字段的时候使用这个函数转换,就可以转回正确的汉字。

//遍历字串的每一个char,转换成byte后组合成byte[],再转换成String返回
//****可以解决因逐个读入char(而不是byte)而组成的字串不能通过encoding还原成中文的问题****
public static String getStrByCharToByte(String str){
byte[] temp=new byte[str.length()];
for(int i=0;i<str.length();i++)
 temp[i]=(byte)(str.charAt(i));
return new String(temp);
}

部分CODE
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[]; 


 类似资料: