Manipular arquivo texto de tamanho grande

4 respostas
G

Boa tarde pessoal, possuo um problema que estou quase louco e não estou conseguindo resolver sozinho.
Preciso criar um editor de texto que suporte manipular arquivos extremamente grandes e o pior, não posso mudar as configurações da vm para a mesma usar mais memória.
Qual seria uma boa solução e uma maneira de implementar isto sendo que tenho que mostrar o conteúdo do arquivo para o usuário em um JTextArea, mas não posso mostrá-lo de uma única vez? e o pior na minha opinião…Como controlar alterações neste arquivo?
Espero ter sido claro no problema e por favor me enviem uma luz!!

Muito obrigado!

4 Respostas

L

gilsonpolito:
Boa tarde pessoal, possuo um problema que estou quase louco e não estou conseguindo resolver sozinho.
Preciso criar um editor de texto que suporte manipular arquivos extremamente grandes e o pior, não posso mudar as configurações da vm para a mesma usar mais memória.
Qual seria uma boa solução e uma maneira de implementar isto sendo que tenho que mostrar o conteúdo do arquivo para o usuário em um JTextArea, mas não posso mostrá-lo de uma única vez? e o pior na minha opinião…Como controlar alterações neste arquivo?
Espero ter sido claro no problema e por favor me enviem uma luz!!

Muito obrigado!

Minha idéia seria você “quebrar” o arquivo em seções. Não fisicamente, mas na hora de ler…

  1. Marque a variável contadora como sendo igual a 1
  2. Marque uma variável de length como sendo 200 (200 linhas)
  3. Faça uma leitura linha a linha do arquivo, a partir de (CONTADORA), em até (LENGTH) linhas
    (exemplo: leitura a partir da linha 1, até a 200, dando 200 linhas)
  4. Remarque a variável contadora para 201.

A partir daí, você vai ter que manipular o JTextArea. Caso o usuário desejar mais linhas atrás (em direção ao início do arquivo), você retorna lê linha a linha, no arquivo, e vai anexando-as ao início do JTextArea, lembrando de remover a mesma quantidade de linhas ao final do campo.

Similarmente, caso o usuário desejar ir mais para o final do arquivo, você lê X linhas adiante e remove do JTextArea X linhas do início.

Ao pensar nesta solução me veio o problema do SCROLL do TextArea… Não sei como você pode manipular isto não mas talvez o componente possua algum método para tal.
Outra possibilidade é você criar uma classe que dá um extends e reimplementar o scroll, que deve resolver seu problema…

Flwz

G

Bom dia LordALMMa,
Primeiro obrigado pelo post. Mas o maior problema ao meu ver é como controlar as alteraçoes do arquivo antes do usuário salvar. Você teria alguma idéia?
[]´s
T+

L

Uma saída simples:

  1. Criar uma variável boolean que inicia com FALSE sempre que o texto for carregado
  2. Ao alterar qualquer conteúdo do texto ela se torna TRUE e não retorna mais para false
  3. Ao efetuar o scroll ou sair, você verifica pela variável. Se for false, basta sair ou carregar outra parte do texto. Se for true, salva os dados que estão sendo exibidos primeiro…

Contudo, esta saída não é das melhores porque se você resolver carregar, por exemplo, 2000 linhas, se ele alterar “A” para “a” na primeira linha, você vai ter que gravar as 2000 no arquivo…

Então, uma saída interessante é:

  1. Faça um List … = new ArrayList(); do mesmo tamanho da quantidade de linhas carregadas
  2. Inicie todo o list com false
  3. Sempre que o usuário alterar uma linha, você altera o array na posição correspondente (cada posição do array equivale a uma linha visível).
  4. Agora é similar ao anterior… Caso altere as linhas visíveis ou saia, vc verifica e salva…

Agora, para salvar vai ser um pouco mais complicado…
=D

Parece que seu maior problema está bem aqui: Identificar aonde você está, no arquivo original, e alterar somente aquela parte.
Bom, você pode fazer assim: Ao carregar o início do texto, você sabe a quantidade total de bytes que foram lidos do arquivo.
Experimente pegar esta quantidade e “pular” ela no arquivo original.

Veja as documentações de READ e WRITE:
http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileInputStream.html#read(byte[],%20int,%20int)
http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileOutputStream.html#write(byte[],%20int,%20int)

Elas foram marcadas nos métodos Read(byte[], int, int) e Write(byte[], int, int) que são justamente o que você precisa.
No read() você passa o array de bytes que vai conter os dados LIDOS, e especifica onde vai COMEÇAR a ler no arquivo e O QUANTO vai ser lido.
Similarmente, tem o write() onde você fala o que vai ser GRAVADO, a partir de ONDE vai ser gravado e O QUANTO vai ser gravado.

Experimente brincar com estes métodos =D
Lembrando que para identificar uma nova linha, você pode sempre recorrer à tabela ASCII, que indica como #10 o NL (new line) e #13 o CR (Carriage Return, a.k.a. ENTER)
-> Tabela ASCII: http://www.asciitable.com/
:slight_smile:

G

Bom dia LordALMMa,

Ontem estive brincando com os métodos proposto por você. Reparei que é possível criar arquivos temporários. Será que não seria uma saída melhor trabalhar com este tipo de arquivo? o grande incoveniente é o alto consumo de IO em disco gerado, mas por outro lado teria uma maior flexibilidade quanto a alteração do arquivo.
O que você acha?

Muito obrigado!
[]´s

Criado 6 de fevereiro de 2008
Ultima resposta 8 de fev. de 2008
Respostas 4
Participantes 2