Java library for fast reading/writing DBF-files.
For build project from sources you need to run gradlew script from the root directory:
git clone git@github.com:jamel/dbf.git
cd dbf
./gradlew clean build
Maven artifact is available from maven central repository. Just add dependency in your pom.xml:
<dependency>
<groupId>org.jamel.dbf</groupId>
<artifactId>dbf-reader</artifactId>
<version>0.0.3</version>
</dependency>
DBF field type | Returned as |
---|---|
character (C) | for reduce memory consumption and improve performance it returns as byte[] . If you need to get a String, use the appropriate constructor of String class. |
date (D) | java.util.Date |
float (F) | java.lang.Float |
logical (L) | java.lang.Boolean |
numeric (N) | java.lang.Number |
In the next example we load data from streets.dbf
mapping each row to objects of Street class:
public class LoadStreetsExample {
public static void main(String[] args) {
File dbf = new File("streets.dbf");
List<Street> streets = DbfProcessor.loadData(dbf, new DbfRowMapper<Street>() {
@Override
public Street mapRow(Object[] row) {
// here we can change string encoding if it is needed
String name = new String(DbfUtils.trimLeftSpaces((byte[]) row[0]));
Number zip = (Number) row[1];
Date createdAt = (Date) row[2];
return new Street(name, zip.intValue(), createdAt);
}
});
System.out.println("Streets: " + streets);
}
}
In the next example we calculate total sum and average price of data from products.dbf
:
public class PricesCalcExampleV1 {
public static void main(String[] args) {
File dbf = new File("products.dbf");
TotalSumCalculator calc = new TotalSumCalculator();
DbfProcessor.processDbf(dbf, calc);
System.out.println("Total sum: " + calc.getTotalSum());
System.out.println("Average price: " + calc.getTotalSum() / calc.getRowsCount());
}
private static class TotalSumCalculator implements DbfRowProcessor {
private double totalSum;
private int rowsCount;
@Override
public void processRow(Object[] row) {
// assuming that there are prices in the 4th column
totalSum += ((Number) row[3]).doubleValue();
rowsCount++;
}
private double getTotalSum() {
return totalSum;
}
private int getRowsCount() {
return rowsCount;
}
}
}
public class DbfInfo {
public static void main(String[] args) {
String dbfInfo = DbfProcessor.readDbfInfo(new File("altnames.dbf"))
System.out.println(dbfInfo);
}
}
Will print:
Created at: 13-7-15
Total records: 39906
Header length: 129
Columns:
# Name Type Length Decimal
---------------------------------------------
0 OLDCODE C 19 0
1 NEWCODE C 19 0
2 LEVEL C 1 0
In the next example we again calculate total sum and average price of data from products.dbf
. But this time we will manually create DbfReader and iterate throughout each row:
public class PricesCalcExampleV2 {
public static void main(String[] args) {
try (DbfReader reader = new DbfReader(new File("products.dbf"))) {
double totalSum = 0;
Object[] row;
while ((row = reader.nextRecord()) != null) {
// assuming that there are prices in the 4th column
totalSum += ((Number) row[3]).doubleValue();
}
System.out.println("Total sum: " + totalSum);
System.out.println("Average price: " + totalSum / reader.getHeader().getNumberOfRecords());
}
}
}
If you have no tool for viewing DBF fields you could simply output all its content to txt file and use your favorite text editor.
public class Dbf2Txt {
public static void main(String[] args) {
DbfProcessor.writeToTxtFile(
new File("altnames.dbf"),
new File("altnames.txt"),
Charset.forName("cp866"));
}
}
To read one or more records at specific positions in the DBF without iterating through all records, you will have to use the DbfReader constructor which takes a File as an argument.
public class RandomRecordAccess {
public static void main(String[] args) {
try (DbfReader reader = new DbfReader(new File("multiple-records.dbf"))) {
// read the tenth record (the indices are zero-based)
reader.seekToRecord(9);
Object[] record = reader.nextRecord();
// process the record ...
// read the third record
reader.seekToRecord(2);
record = reader.nextRecord();
// process the record ...
}
}
}
Dbf writing functionality currently is not available.