Prática recomendada para armazenar grandes quantidades de dados com o J2ME

Estou desenvolvendo um aplicativo J2ME que possui uma grande quantidade de dados para armazenar no dispositivo (na região de 1 MB, mas variável). Eu não posso confiar no sistema de arquivos, então estou preso ao Record Management System (RMS), que permite vários armazenamentos de registros, mas cada um tem um tamanho limitado. Minha plataforma de destino inicial, o Blackberry, limita cada um a 64 KB.

Eu estou querendo saber se alguém mais teve que lidar com o problema de armazenar uma grande quantidade de dados no RMS e como eles conseguiram isso? Estou pensando em calcular tamanhos de registros e dividir um dataset em várias lojas se for muito grande, mas isso adiciona muita complexidade para mantê-lo intacto.

Existem muitos tipos diferentes de dados sendo armazenados, mas apenas um conjunto em particular excederá o limite de 64 KB.

Para qualquer coisa além de alguns kilobytes, você precisa usar o JSR 75 ou um servidor remoto. Os registros RMS são extremamente limitados em tamanho e velocidade, mesmo em alguns aparelhos mais sofisticados. Se você precisa manipular 1 MB de dados no J2ME, a única maneira confiável e portátil é armazená-los na rede. A class HttpConnection e os methods GET e POST são sempre suportados.

Nos aparelhos que suportam JSR 75 FileConnection, pode ser uma alternativa válida, mas sem assinatura de código, é um pesadelo para a experiência do usuário. Quase todas as chamadas de API invocam um prompt de segurança sem nenhuma opção de permissão geral. As empresas que implementam aplicativos com o JSR 75 geralmente precisam de meia dúzia de binários para cada porta apenas para cobrir uma pequena parte dos possíveis certificados. E isso é apenas para os certificados do fabricante; alguns aparelhos só possuem certificados de portadora bloqueada.

O desempenho e a implementação do RMS variam bastante entre os dispositivos, portanto, se a portabilidade da plataforma for um problema, você poderá descobrir que seu código funciona bem em alguns dispositivos e não em outros. O RMS é projetado para armazenar pequenas quantidades de dados (tabelas de pontuações altas ou qualquer outra) e não grandes quantidades.

Você pode achar que algumas plataformas são mais rápidas com arquivos armazenados em várias lojas de registros. Alguns são mais rápidos com vários registros em uma loja. Muitos estão ok para armazenamento, mas se tornam inutilmente lentos ao excluir grandes quantidades de dados da loja.

Sua melhor aposta é usar o JSR-75, quando disponível, e criar sua própria interface de armazenamento de arquivos que retorne ao RMS, se nada for melhor suportado.

Infelizmente, quando se trata de JavaME, muitas vezes você é atraído para escrever variantes específicas do dispositivo do seu código.

Acho que a abordagem mais flexível seria implementar seu próprio sistema de arquivos no topo do RMS. Você pode manipular os registros do RMS de maneira semelhante aos blocos em um disco rígido e usar uma estrutura inode ou semelhante a arquivos lógicos distribuídos em vários blocos. Eu recomendaria implementar uma interface orientada a byte ou stream na parte superior dos blocos e, em seguida, possivelmente fazer outra camada API sobre isso para gravar estruturas de dados especiais (ou simplesmente tornar seus objects serializáveis ​​para o stream de dados).

O livro clássico de Tanenbaum sobre sistemas operacionais cobre como implementar um sistema de arquivos simples, mas eu tenho certeza que você pode encontrar outros resources online se você não gosta de papel.

No Blackberry OS 4.6, o limite de tamanho de loja do RMS foi aumentado para 512Kb, mas isso não ajuda muito, pois muitos dispositivos provavelmente não terão suporte para 4.6. A outra opção no Blackberry é o Armazenamento Persistente, que tem um limite de tamanho de registro de 64kb, mas nenhum limite no tamanho da loja (além dos limites físicos do dispositivo).

Eu acho que Carlos e Izb estão certos.

É bastante simples, use o JSR75 (FileConnection) e lembre-se de assinar seu midlet com um certificado válido (confiável).

Apenas para leitura, chego a tempos aceitáveis ​​(dentro de 10 segundos), indexando um arquivo de recurso. Eu tenho duas exportações de lista de preços CSV de 800KB. As classs do programa e esses dois arquivos são compactados em um JAR de 300 KB.

Na pesquisa, exibo uma List e executo dois Thread em segundo plano para preenchê-la, para que os primeiros resultados sejam bem rápidos e sejam visíveis imediatamente. Primeiro implementei uma pesquisa linear simples, mas isso foi muito lento (~ 2min).

Então eu indexei o arquivo (que é classificado em ordem alfabética) para encontrar o início de cada letra. Agora, antes de analisar linha por linha, primeiro InputStreamReader.skip() para a posição desejada, com base na primeira letra. Eu suspeito que o atraso vem principalmente da descompression do recurso, então dividir os resources iria acelerar ainda mais. Eu não quero fazer isso, não perder a vantagem da atualização fácil. CSV são exportados sem qualquer pré-processamento.

Estou apenas começando a codificar para JavaME, mas tenho experiência com versões antigas do PalmOS, onde todos os blocos de dados são limitados em tamanho, exigindo o design de estruturas de dados usando índices de registros e deslocamentos.

Obrigado a todos por comendas úteis. No final, a solução mais simples era limitar a quantidade de dados armazenados, implementar o código que ajusta os dados de acordo com o tamanho da loja e buscar dados do servidor sob demanda, caso não sejam armazenados localmente. Isso é interessante que o limite é aumentado no OS 4.6, com alguma sorte meu código simplesmente se ajustará por conta própria e armazenará mais dados 🙂

Desenvolver um aplicativo J2ME para o Blackberry sem usar o compilador .cod limita o uso do JSR 75, já que não podemos assinar o arquivo. Como apontado por Carlos, este é um problema em qualquer plataforma e eu tive problemas similares usando a parte do PIM dele. O RMS parece ser incrivelmente lento na plataforma Blackberry, por isso não tenho certeza de como seria útil um sistema de arquivos inode / b-tree, a menos que os dados fossem armazenados em cache na memory e gravados no RMS em um thread secundário de baixa prioridade.