最近做一个DBF数据导入,下载了javadbf-0.4.0.jar包,发现少了对memo字段读入的支持,决定对这个包的DBFReader类进行扩展,实现对memo字段的读入。
memo字段的存储格式:
/*备注头记录
字节偏移 说明
00 - 03 下一个自由块的位置1
04 – 05 未使用
06 – 07 块大小(每个块的字节数)1
08 – 511 未使用
1 存储整数时,高位字节在前。
备注块标头与备注文本
字节偏移 说明
00 – 03 块签名 1 (指示块中数据的类型)
0 – 图片(图片字段类型)
1 – 文本(备注字段类型)
04 – 07 备注长度 1 (以字节为单位)
08 – n 备注文本(n = 长度)
1 存储整数时,高位字节在前。 */
构建一个新的构造函数
public DBFReader( InputStream in, InputStream memo) throws DBFException {
this(in);
// 读入memo内容
try {
this.memoInputStream = new DataInputStream(memo);
this.initMemoInputStream();// 初始化数据流,代码见下面
} catch (IOException e) {
throw new DBFException( e.getMessage());
}
}
private void initMemoInputStream() throws IOException {
memoInputStream.read(new byte[6]); // 00 - 03 下一个自由块的位置1 04 – 05 未使用
blockLength = Utils.readHighEndianShort(memoInputStream); // 06 – 07 块大小(每个块的字节数)1
memoInputStream.read(new byte[504]); // 08 – 511 未使用
}
在nextRecord()方法中,
case 'M':
// TODO Later
这个位置进行memo字段处理,加了如下代码:
case 'M':
// TODO Later
// DBF跳过memo字段
byte b_memoProxy[] = new byte[ this.header.fieldArray[i].getFieldLength()];
dataInputStream.read( b_memoProxy);
// 读取FPT字段
int iType = Utils.readHighEndianInt(memoInputStream);
if (iType == 1) {
int iLength = Utils.readHighEndianInt(memoInputStream);// 红色代码为自己添加的函数
byte b_memo[] = new byte[ iLength];
memoInputStream.read(b_memo); // 读入的FPT文件内容
recordObjects[i] = new String( b_memo, characterSetName);
if (iLength + 8 > blockLength) {
memoInputStream.read(new byte[blockLength - (iLength + 8) % blockLength]);
} else {
memoInputStream.read(new byte[blockLength - 8 - iLength]);
}
}
break;
此时,完成了memo字段的读入,下面附上readHighEndianInt的代码,在Utils类中实现
public static int readHighEndianInt( DataInput in)
throws IOException {
int bigEndian = 0;
for( int shiftBy=24; shiftBy>-1; shiftBy-=8) {
bigEndian |= (in.readUnsignedByte()&0xff) << shiftBy;
}
return bigEndian;
}
public static short readHighEndianShort( DataInput in)
throws IOException {
int high = in.readUnsignedByte();
int low = in.readUnsignedByte() & 0xff;
return (short )(high << 8 | low);
}
到此,读入memo工作全部完成。如果按照这种步骤做下来还有问题,需要源代码,请留言。