Java utility to read/write DBF files
Changed file reading method, using RandomAccessFile instead of BufferedInputStream.
The original net.iryndin.jdbf.reader.DbfReader and net.iryndin.jdbf.reader.MemoReader used BufferedInputStream with buffer size of 1MB, 8KB. This may cause unexpected IOException when stream is read over their buffer size(so the BufferedInputStream's mark is invalidated) and BufferedInputStream.reset() is called. Using RandomAccessFile resolves this problem by seeking around with natively supported method, not reset() and skip()-ing. However, the seeking time might be slightly slower compared to seeking in the buffer, and the support for InputStream(such as net.iryndin.jdbf.reader.DbfReader.DbfReader(InputStream)) is dropped.
Fix issue #5 - don't load DBF and MEMO files into memory when reading it (thanks to Eugene Michuk for noticing this!)
Fix issue #9 - don't define some DBF file types correctly (thanks to l1feh4ck3r!!)
Fix issue #7 - add DbfRecord.isDeleted() method that checks if record is deleted.
Fix issue #3 - read the last record two times for "FoxBASE+/Dbase III plus" files
Fix issue #4 - incorrect parsing of update date in DBF header for "FoxBASE+/Dbase III plus" files
Add ability to read MEMO files (tested with Visual FoxPro DBFs)
Piece of code that reads file from classpath. Single DBF record is represented here as a Map.
public void readDBF() throws IOException, ParseException {
Charset stringCharset = Charset.forName("Cp866");
InputStream dbf = getClass().getClassLoader().getResourceAsStream("data1/gds_im.dbf");
DbfRecord rec;
try (DbfReader reader = new DbfReader(dbf)) {
DbfMetadata meta = reader.getMetadata();
System.out.println("Read DBF Metadata: " + meta);
while ((rec = reader.read()) != null) {
rec.setStringCharset(stringCharset);
System.out.println("Record #" + rec.getRecordNumber() + ": " + rec.toMap());
}
}
}Piece of code that reads DBF and MEMO fields.
See TestMemo.java
public void test1() {
Charset stringCharset = Charset.forName("cp1252");
InputStream dbf = getClass().getClassLoader().getResourceAsStream("memo1/texto.dbf");
InputStream memo = getClass().getClassLoader().getResourceAsStream("memo1/texto.fpt");
try (DbfReader reader = new DbfReader(dbf, memo)) {
DbfMetadata meta = reader.getMetadata();
System.out.println("Read DBF Metadata: " + meta);
DbfRecord rec;
while ((rec = reader.read()) != null) {
rec.setStringCharset(stringCharset);
System.out.println("TEXVER: " + rec.getString("TEXVER"));
// this reads MEMO field
System.out.println("TEXTEX: " + rec.getMemoAsString("TEXTEX"));
System.out.println("TEXDAT: " + rec.getDate("TEXDAT"));
System.out.println("TEXSTA: " + rec.getString("TEXSTA"));
System.out.println("TEXCAM: " + rec.getString("TEXCAM"));
System.out.println("++++++++++++++++++++++++++++++++++");
}
} catch (IOException e) {
//e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}