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 buildMaven 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:
publicclassLoadStreetsExample {
publicstaticvoidmain(String[] args) {
Filedbf = newFile("streets.dbf");
List<Street> streets = DbfProcessor.loadData(dbf, newDbfRowMapper<Street>() {
@OverridepublicStreetmapRow(Object[] row) {
// here we can change string encoding if it is neededStringname = newString(DbfUtils.trimLeftSpaces((byte[]) row[0]));
Numberzip = (Number) row[1];
DatecreatedAt = (Date) row[2];
returnnewStreet(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:
publicclassPricesCalcExampleV1 {
publicstaticvoidmain(String[] args) {
Filedbf = newFile("products.dbf");
TotalSumCalculatorcalc = newTotalSumCalculator();
DbfProcessor.processDbf(dbf, calc);
System.out.println("Total sum: " + calc.getTotalSum());
System.out.println("Average price: " + calc.getTotalSum() / calc.getRowsCount());
}
privatestaticclassTotalSumCalculatorimplementsDbfRowProcessor {
privatedoubletotalSum;
privateintrowsCount;
@OverridepublicvoidprocessRow(Object[] row) {
// assuming that there are prices in the 4th columntotalSum += ((Number) row[3]).doubleValue();
rowsCount++;
}
privatedoublegetTotalSum() {
returntotalSum;
}
privateintgetRowsCount() {
returnrowsCount;
}
}
}publicclassDbfInfo {
publicstaticvoidmain(String[] args) {
StringdbfInfo = DbfProcessor.readDbfInfo(newFile("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:
publicclassPricesCalcExampleV2 {
publicstaticvoidmain(String[] args) {
try (DbfReaderreader = newDbfReader(newFile("products.dbf"))) {
doubletotalSum = 0;
Object[] row;
while ((row = reader.nextRecord()) != null) {
// assuming that there are prices in the 4th columntotalSum += ((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:
DbfRowrow;
while ((row = reader.nextRow()) != null) {
totalSum += row.getDouble("Price");
}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.
publicclassDbf2Txt {
publicstaticvoidmain(String[] args) {
DbfProcessor.writeToTxtFile(
newFile("altnames.dbf"),
newFile("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.
publicclassRandomRecordAccess {
publicstaticvoidmain(String[] args) {
try (DbfReaderreader = newDbfReader(newFile("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 recordreader.seekToRecord(2);
record = reader.nextRecord();
// process the record ...
}
}
}Dbf writing functionality currently is not available.