Como carregar um arquivo na memória?

Estou procurando ajuda de como iniciar, para carregar dados de um arquivo na memória?

tenho um arquivo txt onde faço InputStream e OutPutStream direto, lidando diretamente com o arquivo, lendo, gravando, deletando e atualizando constante. CRUD.

Mas eu gostaria de carregar tudo na memória, e fazer essas operações direto na memória e depois automaticamente replicar isso pro arquivo, automatico ou de alguma outra forma.

Um amigo meu diz que fez isso, mas ele está férias incomunicável, então sei que tem como, mas não sei por onde iniciar.

Queria ajuda de indicações de como fazer, não é pra fazer pra mim não.

detalhe: usando RandomAcessFile.
Obrigado.

Esquecendo do fato que CRUD é para ser feito com um banco de dados, não com um array de strings representando um arquivo-texto na memória, vamos lá.

O que você pode usar é um ArrayList<String> que é lido a partir de um arquivo-texto, usando a classe BufferedReader para ler o arquivo e BufferedWriter para escrevê-lo.

É mais fácil e mais eficiente usar um ArrayList<String> que um array, porque as operações (inserção, remoção, etc.) já estão certas e corrigidas em vez de você ter que fazer tudo na mão (e talvez fazer errado, o que é bastante provável).

Hoje mesmo postei um pseudo-código de como ler e gravar um arquivo-texto - procure por “SedTosco” aqui neste fórum.

[quote=thingol]Esquecendo do fato que CRUD é para ser feito com um banco de dados, não com um array de strings representando um arquivo-texto na memória, vamos lá.

O que você pode usar é um ArrayList<String> que é lido a partir de um arquivo-texto, usando a classe BufferedReader para ler o arquivo e BufferedWriter para escrevê-lo.

É mais fácil e mais eficiente usar um ArrayList<String> que um array, porque as operações (inserção, remoção, etc.) já estão certas e corrigidas em vez de você ter que fazer tudo na mão (e talvez fazer errado, o que é bastante provável).

Hoje mesmo postei um pseudo-código de como ler e gravar um arquivo-texto - procure por “SedTosco” aqui neste fórum.
[/quote]

Thingol, acho que algumas coisas eu pensei “a” e falei “b”.
Na verdade estou desenvolvendo o projeto da SCJD, estou usando RandomAcessFile.
usando getFile().readFully(), getFile().write() … etc
estou tendo alguns problemas, e o maior problema é que o erro ocorre aleatoriamente, as vezes ocorre, outra hora não, este erro é justamente na hora de escrever, eu passo os dados corretos, mas por algum detalhe ele elimina um dígito e bagunça todo meu file.db (mas isso sempre aleatoriamente, isso que é o maior problema, pois não consigo mapeá-lo)

Partindo desse erro, um amigo que fez a scjd a um tempo, falou que não usou diretamente o arquivo, ele carregou na memória e fazia as operações CRUD que foram requisitadas, e o SO cuidava de garantir os dados na memória ficassem sincronizados com o file.db

Acho que isso resolveria meu problema, meu que eu carregue num list, eu poderia usá-lo static pra ser um único fonte de dados, pois poderá ser acessado por vários clientes.
Mas e a questão da sincronização do list com o file.db? Imagine se eu vou guardando e o servidor desliga?
os dados do list não foram para o db e as operações não foram realizadas.
Digo isso, porque me lembro hoje da conversa com meu amigo, ele disse não ter se preocupado com essa questão de ler o arquivo, simplesmente deixou o SO fazer. Mas estou percendo um recurso assim tão automático, pelo menos nunca usei.

primeiramente leia todos os dados do arquivo para uma List de String, ou uma classe específica do seu projeto, você não especificou.
Então cada operação CUD você primeiro executa essas operações na variável List e então simplesmente serializa a list para o arquivo.

Por acaso você está confundindo uma String com um array de bytes? Cuidado com encodings. É que “Ç”, que parece ocupar apenas um byte (e só ocupa um byte em ISO-8859-1 ou em Windows-1252) ocupa 2 bytes em UTF-8.

[quote=thingol][quote]
mas por algum detalhe ele elimina um dígito e bagunça todo meu file.db
[/quote]

Por acaso você está confundindo uma String com um array de bytes? Cuidado com encodings. É que “Ç”, que parece ocupar apenas um byte (e só ocupa um byte em ISO-8859-1 ou em Windows-1252) ocupa 2 bytes em UTF-8.
[/quote]

Pior que não é isso, como todos os dados do arquivo não tem nenhum caracter especial, estou testando sem sempre com caracterers normais, veja só como escrevo:

public int create(String[] data) throws DuplicateKeyException {
		try {
                       //Aqui eu passo meus dados a serem inseridos
                       // Nome  / Cidade / Area / Quantidade / valor / ID Cliente
                       // Ex: new String[]{"Roman", "Sampa", "Information", "4", "$100.00", "12345678" }; 
                       // Primeiro eu normalizo os dados no metodo recordFromArray  
			String strRecord = recordFromArray(data);
			seek(getFile().length());
			getFile().writeByte(VALID_FLAG);
                        // aqui eu escrevo os Bytes dessa String
			getFile().write(strRecord.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return getTotalRecords();
	}

acontece muitas vezes eu rodo e ok, funciona perfeito, as vezes, ele grava apenas 7 dígitos no ID que obrigatoriamente sempre são 8, eu já debuguei e conferi a string chega com cada campo com tamanho certo e os dados corretos, mas quando escreve as vezes vai “1234567” em vez de “12345678”.

Após ele gravar 7 dígitos e SEMPRE deveria ser 8, na próxima gravação ele já se perdeu das posições que deveriam ser e quebra toda minha lógica de leitura. Como eu disse o problema é maior porque isso ocorre simplesmente ALEATÓRIO.
As vezes eu insiro 20 novos registros tudo certo, dai pego o file.bb original e faço novo teste, insiro 1 e já dá erro na escrita com os mesmos dados testados anteiormente.

andreiribas, entendi sua dica. Mas como eu faria pra serializar o list pro file, não seria um write() de minha parte novamente? é uma dúvida de implementação mesmo.

Não é por nada não, mas eu normalmente (até para evitar certos dissabores do tipo “eu tenho uma string de 10 caracteres que ficou com 12 bytes)”, eu uso o método getBytes() da classe java.lang.String passando o encoding “ISO-8859-1”, que sempre codifica cada caracter para 1 byte, ou então para o caracter “?”.

Tome MUITO CUIDADO: não ponha caracteres de 0 a 31, ou acima de 127, dentro de uma string. Eles não são corretamente convertidos para os bytes de 0 a 31 ou de 127 para 255. Alguns dessas caracteres (mesmo com o encoding ISO-8859-1) são convertidos para “?”.

Portanto, não represente um registro como sendo uma string. Cuidado com os bytes :frowning: