Como leer y escribir dbf en java ?

Antes de empezar a documentar este post recuerdo la vez que quería escribir y leer dbf desde java, empece buscando por Internet pero no había mucha documentación disponible hasta que encontré algo y lo voy a replicar por si a alguien mas le sirve ya sea para migrar sus bases de datos.

Aquí les va la url:

http://sarovar.org/docman/view.php/32/23/javadbf-tutorial.html

Aunque esta en ingles me he tomado la molestia de traducirlo en este post para aquellos que no son muy bilingues

Tutorial de la libreria JavaDBF

(for JavaDBF ver. 0.4.0 and above)
Anil Kumar K.
anil at linuxense dot com
Linuxense Information Systems Pvt. Ltd., Trivandrum, India

1. Introducción

JavaDBF es una librería para leer y escribir archivos XBase. Estos son bastantes en aplicaciones legales alrededor de los dbf como su primer formato de almacenamiento. JavaDBF fue inicialmente escrito para transferir datos con aplicaciones. Algo más que, hay requerimientos para exportar datos desde una aplicación java a hojas de calculo como Excel o Lotus 123. Un archivo DBF debe ser mas apropiado en otras situaciones como son el CSV o un archivo HTML porque un archivo DBF puede llevar campos de tipo de información. Mas sobre, formato XBase es como un Open-standard; esto es entendible por casi todos los programas de hojas de calculo.

2. Obteniendo e Instalando

Obtener la ultima versión de JavaDBF desde http://sarovar.org/projects/javadbf/. Crear una carpeta en una ubicación conveniente y hacerlo correr:

	tar xvfz javadbf-x.x.x-tar.gz cd javadbf-x.x.x

En esta carpeta encontraras javadbf.jar que contiene la librería. Incluye este archivo jar en su variable $CLASSPATH variable. Entonces estas listo para avanzar.

3. Resumén de la librería

JavaDBF tiene un simple API propio y no implementa el API JDBC. Es diseñado así porque JavaDBF no esta incluido en el soporte del estilo de interacción con RDBMS. Si estas presumiendo usarlo como un back-end; Simplemente no trabaja de esa forma . Entonces, JavaDBF no es diseñado para hilos seguros; tenlo en mente cuando diseñes aplicaciones de hilos . JavaDBF viene en el paquete com.linuxense.javadbf. Importa ese paquete en tu código java. Los siguientes ejemplos te familiarizaran con este API.

3.1. Tipo de Datos

En la versión 0.3.2, JavaDBF suporta casi todos los tipos de datos XBase excepto el campo Memo. Mientras lee, esos tipos de datos son interpretados como tipo de datos de java apropiados. La siguiente tabla muestra el esquema de datos.

XBase Type XBase Symbol Java Type used in JavaDBF
Character C java.lang.String
Numeric N java.lang.Double
Double F lava.lang.Double
Logical L java.lang.Boolean
Date D java.util.Date

4. Leer un archivo DBF

Al leer un archivo DBF, JavaDBF provee una clase DBFReader. Lo siguiente esta listo para compilar, el programa se explica describiendo casi todas las características de la clase DBFReader. Copiar/Pegar el listado y compilarlo. Manten un archivo .dbf manejable al pasarlo a este programa como un argumento. (Es decir algo que puedas leer, que este a tu alcance).
import java.io.*;
import com.linuxense.javadbf.*;
public class JavaDBFReaderTest {
public static void main( String args[]) {
try {
// create a DBFReader object
//
InputStream inputStream = new FileInputStream( args[ 0]); // take dbf file as program argument
DBFReader reader = new DBFReader( inputStream);
// get the field count if you want for some reasons like the following
//
int numberOfFields = reader.getFieldCount();
// use this count to fetch all field information
// if required
//
for( int i=0; i<numberOfFields; i++) {
DBFField field = reader.getField( i);
// do something with it if you want
// refer the JavaDoc API reference for more details
//
System.out.println( field.getName());
}
// Now, lets us start reading the rows
//
Object []rowObjects;
while( (rowObjects = reader.nextRecord()) != null) {
for( int i=0; i<rowObjects.length; i++) {
System.out.println( rowObjects[i]);
}
}
// By now, we have itereated through all of the rows
inputStream.close();
}
catch( DBFException e) {
System.out.println( e.getMessage());
}
catch( IOException e) {
System.out.println( e.getMessage());
}
}
}

5. Escribiendo un archivo DBF

La clase complementaria a DBFReader es el DBFWriter. Mientras creas un archivo de datos .dbf tendras que tratar con dos aspectos: 1. definir los campos y 2. poblar o abastecer datos. Como mencione antes un campo dbf es representado por la clase DBFField. Primero dejame familiarizarte con esta clase.

5.1. Definiendo Campos

Crear un objeto de la clase DBFField:

  DBFField field = new DBFField();  field.setField( "emp_name"); // give a name to the field

field.setDataType( DBFField.FIELD_TYPE_C); // and set its type

field.setFieldLength( 25); // and length of the field

Bien, ahora un completo objeto DBFField listo para usar. Tenemos creados muchos objetos DBFField como nosotros deseemos en el archivo de datos .dbf. La clase DBFWriter acepta DBFField en un arreglo. Ahora, nos moveremos al próximo paso que sera abastecer de datos o llenarlo con datos.

5.2. Preparando el Objeto DBFWriter

Un DBFWriter es usado para crear un archivo .dbf. Primero crearemos un objetos DBFWriter llamándolo desde su constructor y entonces seteamos sus campos a crear (como esta explicado arriba) llamando con el método setFields.

DBFWriter writer = new DBFWriter();writer.setFields( fields); // fields is a non-empty array of DBFField objects

Ahora, el objeto DBFWriter esta listo para ser llenado. El método para agregar datos al DBFWriter es addRecord y toma un objeto array como argumento. Este objeto array es el que supuestamente contiene los valores para los campos agregados uno a uno correspondiente al campo seteado o declarado anteriormente.

Lo siguiente es un programa completo explicando los pasos descritos en la parte anterior:

import com.linuxense.javadbf.*;
import java.io.*;
public class DBFWriterTest {
public static void main( String args[])
throws DBFException, IOException {
// let us create field definitions first
// we will go for 3 fields
//
DBFField fields[] = new DBFField[ 3];
fields[0] = new DBFField();
fields[0].setName( «emp_code»);
fields[0].setDataType( DBFField.FIELD_TYPE_C);
fields[0].setFieldLength( 10);
fields[1] = new DBFField();
fields[1].setField( «emp_name»);
fields[1].setDataType( DBFField.FIELD_TYPE_C);
fields[1].setFieldLength( 20);
fields[2] = new DBFField();
fields[2].setField( «salary»);
fields[2].setDataType( DBFField.FIELD_TYPE_N);
fields[2].setFieldLength( 12);
fields[2].setDecimalCount( 2);
DBFWriter writer = new DBFWriter();
writer.setFields( fields);
// now populate DBFWriter
//
Object rowData[] = new Object[3];
rowData[0] = «1000»;
rowData[1] = «John»;
rowData[2] = new Double( 5000.00);
writer.addRecord( rowData);
rowData = new Object[3];
rowData[0] = «1001»;
rowData[1] = «Lalit»;
rowData[2] = new Double( 3400.00);
writer.addRecord( rowData);
rowData = new Object[3];
rowData[0] = «1002»;
rowData[1] = «Rohit»;
rowData[2] = new Double( 7350.00);
writer.addRecord( rowData);
FileOutputStream fos = new FileOutputStream( args[0]);
writer.write( fos);
fos.close();

}

Ten en mente que todavia el metodo write es llamado, y todos los datos agregados seran mantenidos en memoria. Entonces, si tu estas planeando escribir un gran monto de datos asegurate que sea seguro ponerlos en memoria hasta que sean escritos a disco y el objeto DBFWriter es garbage-collected. Leer la sección «Sync Mode» para saber como JavaDBF usa una especial caracteristica sobre esto.

5.3. «Sync Mode» –Escribiendo registros a archivos como son agregados

Este es muy usado cuando JavaDBF es usado para crear un DBF con un gran número de registros. En este modo, el mantener registros en memoria para escribir todos en una sola, registros son escritos al archivo como addRecord() es llamado. Aqui esta como escribir en modo Sync Mode:

Crear una instancia DBFWriter pasándole un objeto File que representa uno nuevo/ no existente o archivo vacio. Y lo has hecho! Pero, como en el modo normal, recuerda llamar a write() cuando tengas agregados todos los registros. Esto ayuda a JavaDBF a escribir los meta datos con los valores correctos. Aquí un código de ejemplo:

import com.linuxense.javadbf.*;import java.io.*;public class DBFWriterTest {

public static void main( String args[])

throws DBFException, IOException {

// ...

DBFWriter writer = new DBFWriter( new File( "/path/to/a/new/file")); /* this DBFWriter object is now in Syc Mode */

// ...

}

}

7. Agregando Registros

Desde la version 0.4.0 JavaDBF suporta agregar registros a un archivo DBF existente. Usa el mismo constructor usado en Sync Mode para alcanzar esto. Pero el objeto file pasado al constructor debe representarse por el archivo dbf que los registros seran agregados.

Es ilegal llamar setFields en un objeto DBFWriter creado para agregar datos. Aquí también se requiere llamar el método write después de agregar todos los registros.

6.Características Planeadas

  1. Soporte para campos memo.

52 comentarios en “Como leer y escribir dbf en java ?

  1. hey que buen tutorial, pero aun tengo una duda, si yo imprimo los dato de un .DBF se imprimen en bloques ta cual los lee de la dase de datos, pero si quiero separlos uno por uno debo crear una estructura especial??? o como es la mejor forma d hacerlo???

  2. Como lo puedes ver en el ejemplo todos se leen con un índice.
    me refiero a:
    Object []rowObjects;
    while( (rowObjects = reader.nextRecord()) != null) {

    for( int i=0; i<rowObjects.length; i++) {
    System.out.println( rowObjects[i]);
    }
    }

    Se me ocurre que podrías crearte un modelo es decir:
    tienes en la tabla el id y el nombre
    Entonces al momento de leer tu sabrías que
    setId(rowObject[0]);
    setNombre(rowObject[1]);
    Entonces los leerias por separado.

    Bueno eso es lo que se me ocurre al vuelo.
    Como puedes observar el índice establece que dato lees.

    Espero haber contestado tu inquietud de alguna manera.

    Saludos y Buena suerte

  3. Muchas gracias por la respuesta. Me vas solucionado un gran problema, ahora como todo cuando trabajas en java cuando resuelves algo te sale un nuevo problema. El DBFReader se comprta muy bien con archivos normales pero cuando tienen demasiados registros se guinda osea se queda pegado, se te ha presentado alguna ves eso??? es decir tendras una solucion para ello????
    Gracias nuevamente y Exito

  4. Hola
    Como puedes ver el acceso a los datos es secuencial es decir uno a uno entonces se dará un poco la demora.
    Pero algo que puedes hacer es optimizar el código me refiero a que si estas utilizando por ejemplo, empezar por sacar la comprobacion de longitud del for para que no se ejecute cada vez es decir:

    int total = rowObjects.length;
    for( int i=0; i<total; i++) {

    Saludos y espero haberte ayudado.

  5. Hola como estas, soy principiante en java y estaba viendo como crear dbf en java, estoy probando el codigo q sale en esta pagina y me sale un error,
    Exception in thread «main» java.lang.ArrayIndexOutOfBoundsException: 3
    at prueba.PruebaBbf.main(PruebaBbf.java:56)

    como si el arreglo tuviera las dimensiones equivocadas, que podre estar haciendo mal??

  6. Hola Jesus:

    Puedes utilizarlo tal cual esta en este ejemplo o en su defecto tomar el ejemplo que esta en la pagina en ingles y compilalo ten en cuenta que debes tener la libreria cargada en tu classpath ademas luego de que lo compiles anda anadiendo mas codigo de acuerdo a tu necesidad.
    Lo he probado muchas veces y como ves otras personas que han leido este post tambien y no han tenido ningun problema te invito a que lo compiles tal cual esta el ejemplo aqui y sino mismo te funciona yo te devuelvo el correo para que me envies tu codigo y revisarlo.

    Saludos.

  7. Hola DaRWin,
    Gracias por tu respuesta, y justo estaba programando lo que necesitaba, y logre hacer lo q tenia propuesto, es pasar de una Base de datos oracle a dbf con el programa que estoy elaborando, pero tengo unas dudas, cuando intento abrir un dbf con el visual foxPro 9.0 me sale un error «Table ‘c:\xxx.dbf’ has become corrupted, the table will need to be repaired», por lo q busque en los foros y al parecer es un problema de version, mi pregunta seria como puedo hacer para no tener ese problema.
    Mi otro problema que cuando creo el dbf y los campos numericos se muestran de esta manera ,00 7,36 pero desearia q salga asi 0.00 7.36, como podria hacerlo???

    Muchas Gracias de antemano 😀

  8. Hola DaRWin:
    Muchisimas gracias por la ayuda de la libreria pero me a surgido un problema cuando deseo agregar registros con Sync Mode y no me funciona y no tengo ni idea me podrias explicar un poco mas o enviar un ejemplo para poderlo entender un poco mejor

    de antemano Gracias

  9. alescribirlos en dbf los double los manda con una coma separador de decimales peroen el archivo que necesito los requierocon punto decimal y no coma asi q si ayudan en eso gracias

  10. 100000000000 de gracias por tu trabajo de traducir. La verdad que no se porque los trabajos de traducción nunca son bien valorados.
    Es justo lo que buscaba. Ahora (abuso de tu gentileza) ando buscando la manera más simple de sacar un array (en realidad es la base de datos, o parte de su contenido) en una ventana.
    Gracias mil.-

  11. se podra hacer una tipo consulta osea de los 500 registros que tiene el archivo DBF seleccionar solo los que tengan id > 20 por ejemplo???? se puede hacer eso?’

  12. Hola, como trabajo en la facultad debo realizar un programa web que interactue con una base de datos Fox (extension .DBC, y tablas .DBF), queria saber si este mini tutorial sirve para varias tablas o es mucho lio relacionar tavlas por separado y seria mejor copnectar toda lka base de datos que es :DBC, en este caso como lo harian?

    gracias y por favor necesito respuestas, si malgguno q sabe me escribe a mi mail muy agradecido

    martinr84@gmail.com

  13. Hola, estoy programando algo con archivos DBF pero tengo un problema, cuando leo de un archivo DBF caracteres ñ , ª o cualquiera de esos no me los toma y me los cambia por simbolos raros, ¿como puedo hacer para que lo que lea lo haga en formato iso-8859? ..

    Saludos

  14. alguien me puede ayudar, mi problema es el siguiente:

    tengo un archivo bdf con mas de 9 millones de registros y con esta libreria solo puedo leer poco mas de 500,000 registros.

    lo que pretendo hacer con eso es un migrador, que paso todos estos dato hacia oracle. En este archivo se almacenan el maestro detalle de unas facturas y ps tiene cambios diarios.

    me gustari que me dieran alguna recomendacion y si es podible solucionar esto.

    De ante mani muchas gracias.

  15. Se que es post es un poco antiguo, pero me marca el siguiente error

    Invalid record. Invalid number of fields in row

    Estoy tratando de agregar 33 campos, tendra algo q ver eso?

  16. Hola, soy nuevo x aqui y tengo una pregunta. ¿por que me pone una coma en vez de un punto cuando guardo un decimal? es decir me deberia guardar 6400.00 y no 6400,00. Ademas cuando intento leerlo me saca Failed to parse Number: For input string: «6400,00».

    Agradezco las respuestas.

  17. Hola, gracias por tu ayuda! esta muy buena la información!

    Estoy haciendo una aplicación que crea un tabla dbf y uno de los campos es de tipo fecha (Date), pero cuando tengo que especificar el tamaño me sale error, por ejemplo:

    DBFField fields[] = new DBFField[ 3];
    fields[0] = new DBFField();
    fields[0].setName( “id_tabla”);
    fields[0].setDataType( DBFField.FIELD_TYPE_N);
    fields[0].setFieldLength( 4);
    fields[1] = new DBFField();
    fields[1].setName( “longitud”);
    fields[1].setDataType( DBFField.FIELD_TYPE_N);
    fields[1].setFieldLength( 4); /*********
    fields[1].setDecimalCount( 2); //******
    fields[2] = new DBFField();
    fields[2].setName( “fecha”);
    fields[2].setDataType( DBFField.FIELD_TYPE_D);
    fields[2].setFieldLength( 10); // aqui es donde me sale el error.
    //… siguel el codigo

    Mi pregunta es: con que tamaño se define una fecha (MM/dd/yyyy)? donde me da error.

    Tambien me pasa que cuando asigno los valores Double al cambo 1 (longitud – marcardo como /*******) no me los copia correctamente porque los valores que copio tienen longitudes diferentes, por ejemplo: 125.2 – 23.56; estos se derias guardar en dos registros, en efecto se crean los dos registros pero no se copian los valores, es decir, el campo queda en cero.

    Podrian ayudarme? Muchas gracias!
    Saludos!

  18. Hola a todos.

    Tengo problemas al agregar registros numericos intercambia los puntos y comas. He visto un articulo en el que comentan cambiar el Locale. ¿Sirve también para archivos no nuevos?

    Un saludo

  19. Buen día,
    En la empresa manejamos visual fox pro7 y quiero que una tabla de la base de datos que allí se maneja .dbf (producto.dbf) pueda visualizarla en una aplicación hecha en Java para comparar un campo de allí, por ejemplo código con otra base de datos en este caso Sqlite que ya lo tenía en la aplicación hecha en java.
    Solamente con poder leer la tabla de Vfp7 me serviría mucho.
    Agradezco su valiosa ayuda.

  20. Buenas;
    primeramente gracias por ofrecer la traduccion que es lo que me permitio llegar fasilmente a este post,,
    soy nuevo en java se me hacia nesesario obtener esta libreria la cual probe y me facilita mucho,, pero tengo una duda cuanto quisiera por ejemplo obtener datos de mysql server (es con la que trabajo) y escribir un documento .dbf como lo realizaria de manera sencilla como “Sync Mode” pero no comprendo bien como se maneja si alguien tubiera algun ejemplo por favor me podrian mandar a mi correo

  21. buenas como hago para hacer un if(estatus = 0) donde el “estatus=0″ son de la base de datos y no atributos ni variables de java trabajo con mySQL en NetBeans muchas gracias

  22. Buenas noches no se si aun esten comentando mi problema es este… estoi intentando leer un archivo de VFP y solo me lee unos datos lanzandome el error: Failed to parse Number: For input string: «PROY»
    Como puedo slucionarlo.. soi principiante jeje

    • el archivo ke intento leer es de visual fox pro en .DBF, ya pudimos acceder alos datos de otras tablas pero en una de ellas nos lanza el error que mencione anteriormente..

  23. Hola buenas tardes, disculpa para sobrescribir un archivo DBF ya creado, como se pudiera realizar?

    Como nota el archivo contiene 138 campos y mas de 1000 registros

Replica a Federico Cancelar la respuesta

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.