这是一个漫长的问题,所以请坚持我...
我正在尝试读取一个二进制文件,该文件具有带有记录行的数据库的布局。有两个字节的整数,表示新行/记录的开始。
我对文件的了解是:
它具有以下标签,且其最大长度与之相关
NAME_LENGTH = 32;
LOCATION_LENGTH = 64;
SPECIALTIES_LENGTH = 64;
SIZE_LENGTH = 6;
RATE_LENGTH = 8;
OWNER_LENGTH = 8;
还有一个头文件占据了前72个字节(已用十六进制编辑器标识了,但是我们跳过了这个,所以我从字节72开始读取)。
考虑到这一点,根据我的有限理解,我可以读取每个值可以包含到变量中的字节总数。例如,如果名称为“ John”,则前四个字节将代表John的名称,其余部分为空白。然后,我假设我可以继续读取下一个字节块以获得下一个值。
我整理出一种方法来做到这一点
private Contract retrieveContract(long locationInFile) throws IOException {
final byte[] input = new byte[Contract.RECORD_LENGTH];
synchronized (database) {
database.seek(locationInFile);
database.readFully(input);
}
class RecordFieldReader {
private int offset = 0;
String read(int length) throws UnsupportedEncodingException {
String str = new String(input, offset, length, "UTF-8");
offset += length;
return str.trim();
}
}
RecordFieldReader readRecord = new RecordFieldReader();
String name = readRecord.read(Contract.NAME_LENGTH);
String location = readRecord.read(Contract.LOCATION_LENGTH);
String specialties = readRecord.read(Contract.SPECIALTIES_LENGTH);
String size = readRecord.read(Contract.SIZE_LENGTH);
String rate = readRecord.read(Contract.RATE_LENGTH);
String owner = readRecord.read(Contract.OWNER_LENGTH);
return "DELETED".equals(name) ? null : new Contract(name, location, specialties, size, rate, owner);
}
Contract.x的值在单独的类中如下所述(此处的总体目标是将每个记录读入其自己的对象)
static final int NAME_LENGTH = 32;
static final int LOCATION_LENGTH = 64;
static final int SPECIALTIES_LENGTH = 64;
static final int SIZE_LENGTH = 6;
static final int RATE_LENGTH = 8;
static final int OWNER_LENGTH = 8;
static final int RECORD_LENGTH = NAME_LENGTH
+ LOCATION_LENGTH
+ SPECIALTIES_LENGTH
+ SIZE_LENGTH
+ RATE_LENGTH
+ OWNER_LENGTH;
上面的结果是前几条记录是对齐的,但是随后它们似乎遍地都是
此处以要点输出(有点抱歉)
最后系统崩溃
java.io.EOFException
at java.io.RandomAccessFile.readFully(RandomAccessFile.java:421)
at java.io.RandomAccessFile.readFully(RandomAccessFile.java:399)
at suncertify.db.ContractFileAccess.retrieveContract(ContractFileAccess.java:99)
at suncertify.db.ContractFileAccess.getContractList(ContractFileAccess.java:63)
at suncertify.db.ContractFileAccess.<init>(ContractFileAccess.java:45)
at suncertify.db.Main.main(Main.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
最终的问题来了:如果我不断读取每个字段的最大值并输出,然后移至下一个要读取的块,为什么输出越混乱,输出就越混乱?
原始输入是此处完整性的另一个要点。
有时将其发布到公共场所会使您以不同的方式思考它。问题是我没有考虑两个字节的分隔符。只需在记录长度上加上+2即可解决。
static final int RECORD_LENGTH = 2 + NAME_LENGTH
+ LOCATION_LENGTH
+ SPECIALTIES_LENGTH
+ SIZE_LENGTH
+ RATE_LENGTH
+ OWNER_LENGTH;
谢谢您让StackOverflow成为喧闹和解决问题的地方;)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句