dbf
Java library for fast reading/writing DBF-files.
Build from sources
For build project from sources you need to run gradlew script from the root directory:
git clone [email protected]:jamel/dbf.git
cd dbf
./gradlew clean build
dbf-reader
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>
Supported fields types
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 |
How to use
1. Loading data from small dbf files into collection
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);
}
}
2. Processing each row form dbf file
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;
}
}
}
3. Print general information of DBF-file
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
4. Manually processing rows (low level API)
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());
}
}
}
To get column values you can also use ResultSet-like API. The while loop from the last example can be rewritten like this:
DbfRow row;
while ((row = reader.nextRow()) != null) {
totalSum += row.getDouble("Price");
}
5. Translate DBF to TXT file
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"));
}
}
6. Read DBF records at a specified indices
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-writer
Dbf writing functionality currently is not available.