理解二进制文件

克里斯·特纳

这是一个漫长的问题,所以请坚持我...

我正在尝试读取一个二进制文件,该文件具有带有记录行的数据库的布局。有两个字节的整数,表示新行/记录的开始。

我对文件的了解是:

它具有以下标签,且其最大长度与之相关

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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章