Skip to content

Commit

Permalink
Possibility to read MEMO field as binary data, regardless of field de…
Browse files Browse the repository at this point in the history
…fintion

Fixes #98
  • Loading branch information
albfernandez committed Feb 20, 2024
1 parent 395265f commit a4e9057
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 5 deletions.
12 changes: 8 additions & 4 deletions src/main/java/com/linuxense/javadbf/DBFMemoFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ protected byte[] readBinary(int block) {

protected Object readData(int block, DBFDataType type) {
long blockStart = this.blockSize * (long) block;
DBFDataType usedType = type;
DBFDataType usedType = null;
try {
seek(blockStart);
byte[] blockData = new byte[this.blockSize];
Expand Down Expand Up @@ -196,10 +196,14 @@ else if (intType == 0) {
}
}
byte[] data = baos.toByteArray();
if (usedType != DBFDataType.MEMO) {
return data;

if (usedType == null) {
usedType = type;
}
return new String(data, charset);
if (usedType == DBFDataType.MEMO && type == DBFDataType.MEMO){
return new String(data, charset);
}
return data;

}
catch (IOException ex) {
Expand Down
29 changes: 28 additions & 1 deletion src/main/java/com/linuxense/javadbf/DBFReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

/**
Expand Down Expand Up @@ -155,6 +157,8 @@ public class DBFReader extends DBFBase implements Closeable {
private Map<String, Integer> mapFieldNames = new HashMap<String, Integer>();

private boolean showDeletedRows = false;

private Set<String> fieldsAsBinary = new HashSet<>();

/**
* Intializes a DBFReader object.
Expand Down Expand Up @@ -268,7 +272,26 @@ private Map<String, Integer> createMapFieldNames(DBFField[] fieldArray) {
}
return Collections.unmodifiableMap(fieldNames);
}

/**
* Set the list of memo fields to be readed as binary.
* By default memo fields are retrieved as Strings, but if you know they store binary data
* you can set the names of the memo fields to be recovered unproceesded as byte[]
* @param names name of the memol fields to be treated as binary data.
*/

public void setReadMemoFieldsAsBinary(String... names) {
Set<String> newSet = new HashSet<>();
for (String name: names) {
if (name != null) {
String name1 = name.toUpperCase().trim();
if (name1.length() > 0) {
newSet.add(name1);
}
}
}
this.fieldsAsBinary = newSet;
}

/**
Returns the number of records in the DBF. This number includes deleted (hidden) records
Expand Down Expand Up @@ -534,7 +557,11 @@ private Object readMemoField(DBFField field) throws IOException {
nBlock = DBFUtils.readLittleEndianInt(this.dataInputStream);
}
if (this.memoFile != null && nBlock != null) {
return memoFile.readData(nBlock.intValue(), field.getType());
DBFDataType type = field.getType();
if (type == DBFDataType.MEMO && fieldsAsBinary.contains(field.getName().toUpperCase())) {
type = DBFDataType.BINARY;
}
return memoFile.readData(nBlock.intValue(), type);
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.linuxense.javadbf.bug98;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import com.linuxense.javadbf.DBFReader;
import com.linuxense.javadbf.DBFRow;
import com.linuxense.javadbf.DBFUtils;

public class ReadMemoAsBinaryTest {

public ReadMemoAsBinaryTest() {
super();
}

@Test
public void testReadMemoAsBinary() throws Exception {
File file = new File("src/test/resources/fixtures/dbase_8b.dbf");
DBFReader reader = null;
try {
reader = new DBFReader( new BufferedInputStream(new FileInputStream(file)));
reader.setMemoFile(new File("src/test/resources/fixtures/dbase_8b.dbt"));
reader.setReadMemoFieldsAsBinary("MEMO");
DBFRow row = null;
while ((row = reader.nextRow()) != null) {
byte[] data = row.getBytes("MEMO");
Assertions.assertTrue(data == null || data instanceof byte[]);
}

}
finally {
DBFUtils.close(reader);
}
}

}

0 comments on commit a4e9057

Please sign in to comment.