使用 J2ME 存储大量数据的最佳实践
我正在开发一个 J2ME 应用程序,该应用程序需要在设备上存储大量数据(在 1MB 左右但可变的区域)。 我不能依赖文件系统,因此我只能使用记录管理系统 (RMS),该系统允许多个记录存储,但每个记录存储的大小有限。 我最初的目标平台 Blackberry 将每个平台限制为 64KB。
我想知道是否有其他人必须解决在 RMS 中存储大量数据的问题以及他们如何管理它? 我正在考虑必须计算记录大小并在多个存储中分割一个数据集(如果它太大),但这会增加很多复杂性以保持其完整。
存储了许多不同类型的数据,但只有一组数据会超过 64KB 限制。
I am developing a J2ME application that has a large amount of data to store on the device (in the region of 1MB but variable). I can't rely on the file system so I'm stuck the Record Management System (RMS), which allows multiple record stores but each have a limited size. My initial target platform, Blackberry, limits each to 64KB.
I'm wondering if anyone else has had to tackle the problem of storing a large amount of data in the RMS and how they managed it? I'm thinking of having to calculate record sizes and split one data set accross multiple stores if its too large, but that adds a lot of complexity to keep it intact.
There is lots of different types of data being stored but only one set in particular will exceed the 64KB limit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
对于只读,我通过索引资源文件在可接受的时间(10 秒内)到达。 我有两个 ~800KB CSV 价目表导出。 程序类和这两个文件都压缩为 300KB JAR。
在搜索时,我显示一个
List
并在后台运行两个Thread
来填充它,因此第一个结果很快就会出现,并且可以立即查看。 我首先实现了一个简单的线性搜索,但这太慢了(~2 分钟)。然后我索引该文件(按字母顺序排序)以查找每个字母的开头。 现在,在逐行解析之前,我首先根据第一个字母
InputStreamReader.skip()
到所需的位置。 我怀疑延迟主要来自解压缩资源,因此分割资源会进一步加快速度。 我不想这样做,以免失去轻松升级的优势。 CSV 无需任何预处理即可导出。For read only I'm arriving at acceptable times (within 10s), by indexing a resource file. I've got two ~800KB CSV price list exports. Program classes and both those files compress to a 300KB JAR.
On searching I display a
List
and run a twoThread
s in the background to fill it, so the first results come pretty quickly and are viewable immediately. I first implemented a simple linear search, but that was too slow (~2min).Then I indexed the file (which is alphabetically sorted) to find the beginnings of each letter. Now before parsing line by line, I first
InputStreamReader.skip()
to the desired position, based on first letter. I suspect the delay comes mostly from decompressing the resource, so splitting resources would speed it up further. I don't want to do that, not to loose the advantage of easy upgrade. CSV are exported without any preprocessing.我刚刚开始为 JavaME 编写代码,但有使用旧版本 PalmOS 的经验,其中所有数据块的大小都受到限制,需要使用记录索引和偏移量设计数据结构。
I'm just starting to code for JavaME, but have experience with old versions of PalmOS, where all data chunks are limited in size, requiring the design of data structures using record indexes and offsets.
感谢大家的有用评论。 最后,最简单的解决方案是限制存储的数据量,实现根据存储大小调整数据的代码,如果数据未存储在本地,则按需从服务器获取数据。 有趣的是,OS 4.6 中的限制增加了,幸运的是,我的代码将简单地自行调整并存储更多数据:)
在不使用 .cod 编译器的情况下为 Blackberry 开发 J2ME 应用程序会限制 JSR 75 的使用,因为我们无法签署档案。 正如 Carlos 所指出的,这在任何平台上都是一个问题,我在使用 PIM 部分时也遇到过类似的问题。 RMS 在 Blackberry 平台上似乎非常慢,因此我不确定顶部的 inode/b-tree 文件系统有多大用处,除非数据缓存在内存中并在低优先级后台线程中写入 RMS。
Thanks everyone for useful commments. In the end the simplest solution was to limit the amount of data being stored, implementing code that adjusts the data according to how large the store is, and fetching data from the server on demand if its not stored locally. Thats interesting that the limit is increased in OS 4.6, with any luck my code will simply adjust on its own and store more data :)
Developing a J2ME application for Blackberry without using the .cod compiler limits the use of JSR 75 some what since we can't sign the archive. As pointed out by Carlos this is a problem on any platform and I've had similar issues using the PIM part of it. The RMS seems to be incredibly slow on the Blackberry platform so I'm not sure how useful a inode/b-tree file system on top would be, unless data was cached in memory and written to RMS in a low priority background thread.
在 Blackberry OS 4.6 中,RMS 存储大小限制已增加至 512Kb,但这并没有多大帮助,因为许多设备可能不支持 4.6。 Blackberry 上的另一个选项是持久存储,它的记录大小限制为 64kb,但存储大小没有限制(设备的物理限制除外)。
我认为卡洛斯和 izb 是对的。
Under Blackberry OS 4.6 the RMS store size limit has been increased to 512Kb but this isn't much help as many devices will likely not have support for 4.6. The other option on Blackberry is the Persistent Store which has a record size limit of 64kb but no limit on the size of the store (other than the physical limits of the device).
I think Carlos and izb are right.
这很简单,使用 JSR75 (FileConnection) 并记住使用有效(可信)证书签署您的 midlet。
It is quite simple, use JSR75 (FileConnection) and remember to sign your midlet with a valid (trusted) certificate.
我认为最灵活的方法是在 RMS 之上实现您自己的文件系统。 您可以以与硬盘驱动器上的块类似的方式处理 RMS 记录,并使用 inode 结构 或类似于将逻辑文件分布在多个块上。 我建议在块的顶部实现一个面向字节或流的接口,然后可能在其上创建另一个 API 层来编写特殊的数据结构(或者只是使您的对象可序列化到数据流)。
Tanenbaum 有关操作系统的经典书籍 介绍了如何实现简单的文件系统,但是我相信如果您不喜欢纸张,您可以在网上找到其他资源。
I think the most flexible approach would be to implement your own file system on top of the RMS. You can handle the RMS records in a similar way as blocks on a hard drive and use a inode structure or similar to spread logical files over multiple blocks. I would recommend implementing a byte or stream-oriented interface on top of the blocks, and then possibly making another API layer on top of that for writing special data structures (or simply make your objects serializable to the data stream).
Tanenbaum's classical book on operating systems covers how to implement a simple file system, but I am sure you can find other resources online if you don't like paper.
不同设备之间的 RMS 性能和实现差异很大,因此,如果平台可移植性存在问题,您可能会发现您的代码在某些设备上运行良好,而在其他设备上则运行不佳。 RMS 旨在存储少量数据(高分表或其他数据),而不是大量数据。
您可能会发现,某些平台将文件存储在多个记录存储中时速度更快。 有些在一个商店内有多个记录,速度更快。 许多存储都可以,但是当从存储中删除大量数据时,速度会变得非常慢。
最好的选择是在可用的情况下使用 JSR-75,并创建您自己的文件存储界面,如果没有更好的支持,则回退到 RMS。
不幸的是,当涉及到 JavaME 时,您经常会被迫编写特定于设备的代码变体。
RMS performance and implementation varies wildly between devices, so if platform portability is a problem, you may find that your code works well on some devices and not others. RMS is designed to store small amounts of data (High score tables, or whatever) not large amounts.
You might find that some platforms are faster with files stored in multiple record stores. Some are faster with multiple records within one store. Many are ok for storage, but become unusably slow when deleting large amounts of data from the store.
Your best bet is to use JSR-75 instead where available, and create your own file store interface that falls back to RMS if nothing better is supported.
Unfortunately when it comes to JavaME, you are often drawn into writing device-specific variants of your code.
对于超过几千字节的任何内容,您需要使用 JSR 75 或远程服务器。 即使在一些高端手机中,RMS 记录的大小和速度也极其有限。 如果您需要在 J2ME 中处理 1MB 的数据,唯一可靠、可移植的方法是将其存储在网络上。 始终支持 HttpConnection 类以及 GET 和 POST 方法。
在支持 JSR 75 FileConnection 的手机上,它可能是有效的替代方案,但如果没有代码签名,这将是用户体验的噩梦。 几乎每个 API 调用都会调用安全提示,而没有任何权限选择。 使用 JSR 75 部署应用程序的公司通常需要每个端口六个二进制文件,才能覆盖一小部分可能的证书。 这仅适用于制造商证书; 某些手机仅具有运营商锁定的证书。
For anything past a few kilobytes you need to use either JSR 75 or a remote server. RMS records are extremely limited in size and speed, even in some higher end handsets. If you need to juggle 1MB of data in J2ME the only reliable, portable way is to store it on the network. The HttpConnection class and the GET and POST methods are always supported.
On the handsets that support JSR 75 FileConnection it may be valid alternative but without code signing it is an user experience nightmare. Almost every single API call will invoke a security prompt with no blanket permission choice. Companies that deploy apps with JSR 75 usually need half a dozen binaries for every port just to cover a small part of the possible certificates. And this is just for the manufacturer certificates; some handsets only have carrier-locked certificates.