我手动序列化的数据对象到一个文件,使用字节缓冲区和它的操作,如putInteger()
,putDouble()
等的Java NIO:写入文件头 - 使用SeekableByteChannel
一个我想为写字段out是一个String。举例来说,假设这包含一种货币。每种货币都有一个三字母的ISO货币代码,例如英镑为英镑。
假设我序列化的每个对象只有一个double和一个货币;你可以考虑序列化的数据看起来是这样的:
100.00|GBP
200.00|USD
300.00|EUR
很显然,在现实中我没有界定的数据(场之间的管道,也不是换行),它存储在二进制 - 只是用上面一个例证。
对每个条目进行货币编码有点低效,因为我一直保存相同的三个字符。相反,我想要一个标题 - 存储货币映射。该文件看起来是这样的:
100
GBP
USD
EUR
~~~
~~~
100.00|1
200.00|2
300.00|3
的文件中的第2个字节是一个简短的,充满十进制值100。这告诉我说,有100个停车位的文件中的货币。在此之后,有3个字节的组块(顺序为货币)(仅ASCII字符)。
当我重新读取文件时,我所要做的就是构建一个包含货币代码的100个元素的数组,并且我可以便宜/有效地查找每行的相关货币。
读取文件后退似乎很简单。但我有兴趣听到关于写出数据的想法。
我并不知道所有的货币,我实际上支持任何三字符的代码 - 即使它是无效的。因此,我必须建立表格,将货币转换为即时索引。
我打算使用SeekableByteChannel来寻址我的文件,并且每次找到一个我以前没有编入索引的新货币时都会回头查找头文件。
这对移动文件有明显的I/O开销。但是,我期待在前几个数据对象内看到所有不同的货币。所以它可能只会寻找执行的前几秒钟,然后不需要额外搜寻几个小时。
另一种方法是等待数据流完成,然后再写入一次头。但是,如果我的应用程序崩溃并且我没有写出头文件,则文件中的数据无法恢复到其原始内容。
寻求似乎是正确的事情,但我以前没有尝试过 - 并且希望能够预先听到恐怖故事,而不是通过我的尝试/错误。
您是否考虑过使用嵌入式数据库?否则,它会像我正在重新发明轮子一样,像交易数据库一样寻找我。 – Robert
@Robert我正在存储的数据需要进行索引才能进行快速访问。鉴于我的数据是固定宽度,我可以非常快速地找到第n个元素,找到数据有效负载的开始,然后寻找n *对象大小的字节。我将存储数以百万计的记录,并且输入速率非常“突然” - 在每天的特定时间,我可以每秒收到数十万条记录。我正在寻找速度非常快的东西,我不一定需要具有类似SQL的嵌入式数据库的所有功能的东西。像Derby/HSQLDB这样的产品太慢了。 – jwa
好的,如果你想自己编码一个优化版本使用两个文件,一个用于货币,一个用于数据,那么你不必考虑偏移量... – Robert