`
guoyiqi
  • 浏览: 1010723 次
社区版块
存档分类
最新评论

通过java动态创建ODBC数据源来访问DBF文件

阅读更多

想用java语言来处理。最终还是需要通过JNI来处理,不过用到了一个开元的操作注册表的registry-3.1.3,使用后,发现蛮简单的,网上已有很多资料介绍,就不多说了。

想了两种解决方法,第一种比较麻烦,但是看网上很多人问,就也总结了出来,其实就是通过java动态创建ODBC数据源来访问DBF文件,这个就需要用到registry,来修改注册表了。

 

其实,主要是动态创建ODBC数据源,开始很简单,可以手工设置一次数据源,当然也可以通过程序直接生成,问题都不大。下面只说怎样修改。

 

import com.ice.jni.registry.RegStringValue;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryKey;

 

 

public class TestC {
 public static void main(String[] str) {
        try {
         
              RegistryKey child = Registry.HKEY_CURRENT_USER
                      .openSubKey("Software").openSubKey("ODBC").openSubKey
("ODBC.INI").openSubKey("data_0930",RegistryKey.ACCESS_ALL);//
操作权限是通过RegistryKey来获取的。
              String de = "F:\\commony\\test\\data\\070901";  //
我的DBF数据的目录//其中,data_0930是我第一次设置的数据源的一个注册表的名称
              System.out.println(child.getStringValue("SourceDB"));
             child.setValue(new RegStringValue(child,"SourceDB",de));
              System.out.println(child.getFullName());
        } catch (Exception e) {
              e.printStackTrace();
        }
    }

}

 

然后就是通过,sun.jdbc.odbc.JdbcOdbcDriver来获取数据,

 

import java.sql.DriverManager;
import java.sql.*;
public class TestOdbc {
  public TestOdbc() {
  }
  public static void main(String[] args) {
    java.sql.Connection conn = null;
    java.sql.PreparedStatement pt = null;
    java.sql.ResultSet rs = null;
    try {
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    }
    catch (ClassNotFoundException ex1) {
    }
    try {
      conn = DriverManager.getConnection("jdbc:odbc:data_0930", "", "");
      pt = conn.prepareStatement(" select *  from test_table");
      rs = pt.executeQuery();
      while(rs.next()){
        System.out.println("==="+rs.getString(1));
        System.out.println("==="+rs.getString(2));
        System.out.println("==="+rs.getString(3));
        System.out.println("==="+rs.getString(4));
        System.out.println("==="+rs.getString(5));
      }
    }
    catch (SQLException ex) {
    }
  }
}

 

其实真的很简单。

其实,文件名,是可以动态获取的,一般可以通过java中的File类来获取:

 

import java.io.File;


public class TestD {

 public static void main(String[] args){
  File file = new File("F:\\commony\\test\\data");
  File[] df = file.listFiles();
  for(int k =0;k   if(df[k].isDirectory()){ //
因为文件夹中包含DBF文件,所以判断是文件夹,而不是文件
    System.out.println("===kkkk=="+k+"====="+df[k].getName());
   }
  }
 }
}

 

第一种就是这样,需要注意的是registry的使用,其实很简单的,只要把DLL文件放到classpath下就可以了。

第二种其实更简单,就是通过另一个开元的类包jdbf.jar,使用方法也很简单,网上有很多资料,可以查询。也就不多说了。

 

完全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 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[];
}

分享到:
评论
1 楼 shgaoyuhai 2011-11-28  
请问一下,如果dbf文件里有删除标示的语句是隐藏的,直接执行sql是查不出来的,该怎么办?

相关推荐

    ODBC驱动安装程序,用于读取DBF文件

    DBF文件是FoxPro、dBase等数据库管理系统中常见的数据文件格式,其中存储了结构化的表格数据。 1. ODBC简介: ODBC是一个由Microsoft开发的API,它提供了一个标准的接口,使得程序员可以编写一次应用程序,然后在...

    DBF数据源驱动

    2. 创建ODBC数据源:在控制面板中找到ODBC管理器,创建一个新的系统DSN(数据源名称),选择VFPODBC驱动,并配置指向DBF文件的位置。 3. 配置Oracle连接:确保已经安装了适用于Oracle 11g的JDBC驱动,并在应用程序中...

    java解析dbf文件方案.pdf

    Java 解析 DBF 文件方案 Java 解析 DBF 文件方案是使用 Java ...Java 解析 DBF 文件方案提供了两种方法来读取和解析 DBF 文件,使用 ODBC 驱动和 javadbdf 库,可以根据实际情况选择合适的方法来读取和解析 DBF 文件。

    java快速导出几十万百万生成DBF文件数据后台内附有javadbf.jar

    本文将深入探讨如何使用Java来快速导出大量数据到DBF文件,以及如何利用`javadbf.jar`库进行高效操作。 首先,DBF文件是基于dBase III、IV或FoxPro等早期数据库管理系统的文件格式。它以ASCII文本存储表格数据,...

    java 实现DBF文件读取与创建

    DBF(dBase File)是一种...通过以上步骤,你可以在Java环境中轻松实现DBF文件的读取与创建。不过,需要注意的是,尽管JDBF库提供了方便的接口,但在实际应用中,可能还需要根据具体需求进行一些自定义的处理或扩展。

    配置 ODBC 数据源

    ODBC正是一种这样的解决方案,它提供了一种标准化的方式来配置和访问这些数据源。配置ODBC数据源可以实现以下功能: - **提高应用灵活性**:应用程序可以通过ODBC连接到多种数据库,提高了其对不同数据库的支持能力...

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

    使用 Java 实现对 dbf 文件的简单读写 Java 是一种广泛使用的编程语言,对于读写 dbf 文件具有重要的应用价值。本文将介绍使用 Java 实现对 dbf 文件的简单读写,包括读写 dbf 文件的基本步骤、相关类的介绍、代码...

    DBF数据导入oracle表处理方法

    为了实现这个过程,需要正确创建 DBF 的 ODBC 数据源,然后使用 PL/SQL 导入 DBF 文件。 创建 DBF 的 ODBC 数据源 在 Windows 7 操作系统中,创建 DBF 的 ODBC 数据源需要遵循以下步骤: 1. 进入控制面板中的系统...

    JAVA 读取dbf文件

    虽然不是直接针对DBF,但可以通过设置ODBC数据源来间接访问。首先,需要在系统中创建一个指向DBF文件的ODBC数据源,然后使用JDBC的`DriverManager.getConnection()`方法连接到这个数据源。 3. **JDBF库**: JDBF是...

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

    JavaDBF库正是利用这些信息来解析和创建DBF文件。 在使用JavaDBF进行读操作时,你需要先创建一个DBFReader对象,传入DBF文件的路径。通过这个对象,你可以获取表的字段信息,遍历并读取所有记录。例如: ```java ...

    java操作dbf文件

    在给定的压缩包`javadbf-0.4.0`中,可能包含了这个库的源代码、文档和相关的示例,这使得开发者能够理解和使用这个库来完成读写DBF文件的任务。 1. **读取DBF文件**: 使用`javadbf`库,你可以创建一个`DbfFile`...

    java快速导出几十万百万生成DBF文件数据后台

    对于DBF文件的生成,Java中没有内置支持,但可以通过第三方库如`JDBF`或者`dbf4j`来实现。这些库提供了API,能够方便地创建、写入和读取DBF文件。 1. **JDBF库**:提供了一种简单的方式创建DBF文件,包括定义字段...

    LINUX平台JAVA直接连接access数据库dbf文件

    2. **配置ODBC数据源**:安装完成后,需要创建一个ODBC数据源,指向Access数据库的DBF文件。这通常通过编辑`/etc/odbc.ini`和`/etc/odbcinst.ini`文件完成,定义DSN(数据源名称)、驱动和数据库路径。 3. **Java...

    java生成dbf文件

    根据需求生成dbf文件,根据模板dbf文件生成特定格式的dbf文件,可以帮助解决项目中的特殊需求问题,更好地完整项目。 dbf文件是一种存储数据的格式,所以在某些需求中,会需要使用。

    java 读写 DBF 文件 xBaseJ

    本篇文章将详细探讨如何使用Java来读写DBF文件,重点介绍xBaseJ库,这是一个专门为Java设计的、用于处理DBF文件的开源库。 首先,我们要理解DBF文件的结构。DBF文件是一种基于文本的数据库格式,由一系列记录组成,...

    java读取DBF解决方案(可以解决javadbf.jar对DBF部分中文乱码和错行等杂症)

    2、创建ODBC数据源 DBF的ODBC建立方法: X86server,进入 控制面板--系统和安全--管理工具--ODBC数据源--右键管理员方式运行 X64(win7,server):C:\windows\sysWow64\odbcad32.exe 右键管理员方式运行,如图1 在...

    dbf-jdbc-wisecoders,JAVA 读写DBF文件工具包

    1. **JDBC接口**:`dbf-jdbc-wisecoders`通过提供一个类似于JDBC(Java Database Connectivity)的接口,让Java开发者可以使用他们熟悉的SQL查询来访问和操作DBF文件。这大大简化了代码编写,使得DBF文件的处理如同...

    java解析dbf文件三种方法、以及解析驱动

    DBF(dBase File)是一种常用的数据文件格式,最初由dBase数据库应用程序创建并使用。它以表格形式存储数据,支持多种不同的数据库管理系统(DBMS)。由于其简单且开放的特性,DBF文件在很多场景下被广泛采用,尤其...

    C++ 操作dbf文件(深入剖析dbf文件)

    在C++中,我们可以创建结构体或类来映射DBF文件中的记录结构,方便数据的处理和存储。这可以通过定义一个包含对应字段类型的成员变量的类来实现,然后在读取记录时将数据填充到实例中。 在实际应用中,我们可能会...

Global site tag (gtag.js) - Google Analytics